Declarative properties

  • Thread starter Bruno Desthuilliers
  • Start date
B

Bruno Desthuilliers

Artur Siekielski a écrit :
It's a perfect summary of my thoughts after reading this thread. I
will use public attributes (with access customizable with properties)
and remember that in Python I can do everything :).

Well... Almost !-)

And +1 QOTW, BTW.
 
S

Stargaming

On Thu, 11 Oct 2007 18:58:44 +0200, Bruno Desthuilliers wrote:
[snip]

Your implementation seems particularly broken. You do not return anything
from `name()`, hereby removing name as an attribute (or: replacing it
with its return value -- None). You should return ``property(**locals())
`` (or ``property(fget=fget, fset=fset, ...)``, whatever you like).

I'm going to point out a few other mistakes first:
class Toto(object):
def __iinit__(self, name):

Typo here: __init__
self.name = name
@apply
def name():
def fget(self):
print "getting %s.name" % self
return self._name
def fset(self, val):
print "setting %s.name to %s" % (self, val)
self._name = name

It should be `val`, not `name`, huh? And, as mentioned above, the return
value is missing.
def say_hello(self):
print "Hello, my name is %s" % self.name

A fixed implementation could be something along these lines::
... def __init__(self, name):
... self.name = name
... @apply
... def name():
... def fget(self):
... print "getting %s.name" % self
... return self._name
... def fset(self, val):
... print "setting %s.name to %s" % (self, val)
... self._name = val
... return property(**locals())
... def say_hello(self):
... print "Hello, my name is %s" % self.name
... getting <__main__.Toto object at 0xb792f66c>.name
Hello, my name is jon

Cheers,
Stargaming
 
D

Dan Stromberg

1/ Accessing the value of a property is not free. Accessing a plain
attribute is much cheaper.

Python's current performance characteristics have no bearing on what is
good software engineering practice in general, and little bearing on what
is good software engineering practice in python. Even from a
strictly "what's good for python" perspective, if we limit our view of
"good SE practice" to what python can express well right now (and IMO,
python can express this fine, but you seem to be arguing it cannot),
that needlessly limits python's evolution.

I'm not omniscient, and neither is anyone else; when one initially codes a
class, one doesn't know to what purposes it will need to be bent in the
future; using accessor methods instead of exposed attributes is
significantly more flexible for the future of your class. In fact, I may
even go so far as to say that public attributes would be good to leave out
of future languages that don't have a lot of backward compatibility
baggage.

It may not be traditional to use accessor methods in python. It may even
be a more expensive operation. But neither of these make accessor methods
a bad idea in the abstract.
2/ cluttering the class's namespace with useless names and the source
code with useless code is definitively not a good thing.

Adding two clear and flexible methods and eliminating one clear and
inflexible attribute is not namespace clutter. It's paydirt.

The performance expense in the vast majority of cases is tiny compared to
the human expense of going back and fixing a design bug if anything
significant has been hinging on your exposed implementation detail.

Unless, that is, you don't think your code is important enough to be
stretched to another, previously unforeseen purpose someday. If you're
coding for a hobby, and enjoy coding for the sake of coding irrespective
of how long it takes, rather than as a means to a valuable end, maybe
needlessly exposing attributes is a Really Good Idea.

My implementation may or may not be lacking (feel free to improve it - in
fact, please do!), but that's irrelevant to the heart of the matter, which
is "what you didn't think to plan for now most definitely can hurt you
later".

If you have a program that needs to perform well, you're much better off
coding your classes the best way you know how from a Software Engineering
perspective, and using pysco or shedskin or pypy or similar to
improve performance. If that's not enough, then you're better off
profiling the program, and only after that should you recode the critical
portions into something like pyrex or a C extension module, or -maybe-
some python "tricks". I'd argue that trick-free C or C++ is normally
better than python with tricks from a performance vantage -and- from an SE
viewpoint.

Little hackish tricks for performance's sake scattered throughout a
program are very wasteful of something more precious than CPU time.
 
G

George Sakkis

If you have a program that needs to perform well, you're much better off
coding your classes the best way you know how from a Software Engineering
perspective, and using pysco or shedskin or pypy or similar to
improve performance.

"best way you know how from a Software Engineering" != "best way to do
it in less flexible languages that will go unnamed, such as Java"

You seem to conflate these two.

George
 
D

Dan Stromberg

Sorry I don't get it. If I want to customize the access to a "normal"
attribute I simply turn it into a property.

You're right, properties are an intersting language feature. I wasn't
aware of them until today.

I'm not sure I believe they are better than disallowing public attributes
and requiring setters and getters, but they do appear to address the same
issue: the needless change in API when your internal representation
needs to change.

Apologies.
 
C

Chris Mellon

Python's current performance characteristics have no bearing on what is
good software engineering practice in general, and little bearing on what
is good software engineering practice in python. Even from a
strictly "what's good for python" perspective, if we limit our view of
"good SE practice" to what python can express well right now (and IMO,
python can express this fine, but you seem to be arguing it cannot),
that needlessly limits python's evolution.

I'm not omniscient, and neither is anyone else; when one initially codes a
class, one doesn't know to what purposes it will need to be bent in the
future; using accessor methods instead of exposed attributes is
significantly more flexible for the future of your class.

This is simply not true in Python, and anyone who thinks it is hasn't
the slightest understanding of the consequences of dynamic vs static
lookup. The best practice (in C++, which Java inherited) of using
accessors is because changing a public attribute to a property broke
your interface, and all the clients of your code needed to be altered.
Later languages, like C#, introduced syntax support for properties,
which improved the situation such that clients didn't need to be
re-written, but only recompiled.

Python, however, uses truly dynamic attribute lookup and there is
*zero* cost to clients in a change from a public attribute to a
property.

Writing accessors in a language that doesn't have the pressures that
introduced them is cargo cult programming, not Software Engineering.
In fact, I may
even go so far as to say that public attributes would be good to leave out
of future languages that don't have a lot of backward compatibility
baggage.
From a reasonable point of view, Python doesn't have public
attributes, it just has things that syntactically look like them.
Discuss!
It may not be traditional to use accessor methods in python. It may even
be a more expensive operation. But neither of these make accessor methods
a bad idea in the abstract.

Of course not, that's why Python supports properties. What's being
called the anti-pattern here is the creation-by-default of trivial
accessors.
Adding two clear and flexible methods and eliminating one clear and
inflexible attribute is not namespace clutter. It's paydirt.

No, you kept the attribute and also added (at least) 2 methods.
The performance expense in the vast majority of cases is tiny compared to
the human expense of going back and fixing a design bug if anything
significant has been hinging on your exposed implementation detail.

You still don't know what language you're writing in, do you? There is
zero additional cost associated with changing a public attribute to a
property.
Unless, that is, you don't think your code is important enough to be
stretched to another, previously unforeseen purpose someday. If you're
coding for a hobby, and enjoy coding for the sake of coding irrespective
of how long it takes, rather than as a means to a valuable end, maybe
needlessly exposing attributes is a Really Good Idea.

Ah, the old "my code is way more important than yours, so what I do is
right" approach. You hang out in the Java world a lot, don't you?
My implementation may or may not be lacking (feel free to improve it - in
fact, please do!), but that's irrelevant to the heart of the matter, which
is "what you didn't think to plan for now most definitely can hurt you
later".

Your implementation is, quite possibly, the worst possible
implementation of automatic properties in Python, both in terms of
readability and code size (and thus maintenance), as well as
performance and flexibility. The fact that you consider it, even for a
moment, to be better than writing accessors when and if you need them
(and not writing them otherwise) belies a dreadful lack of self
awareness.
If you have a program that needs to perform well, you're much better off
coding your classes the best way you know how from a Software Engineering
perspective, and using pysco or shedskin or pypy or similar to
improve performance. If that's not enough, then you're better off
profiling the program, and only after that should you recode the critical
portions into something like pyrex or a C extension module, or -maybe-
some python "tricks". I'd argue that trick-free C or C++ is normally
better than python with tricks from a performance vantage -and- from an SE
viewpoint.

You're not going to teach anyone on this list anything about
optimizing, I suspect.
Little hackish tricks for performance's sake scattered throughout a
program are very wasteful of something more precious than CPU time.

It's truly bizarre to hear someone refer to *not* writing code as a
"hackish trick". Especially when the alternative they prevent depends
on eval!
 
D

Diez B. Roggisch

Dan said:
You're right, properties are an intersting language feature. I wasn't
aware of them until today.

I'm not sure I believe they are better than disallowing public attributes
and requiring setters and getters, but they do appear to address the same
issue: the needless change in API when your internal representation
needs to change.

This belief is most probably nurtured by Java. Or am I wrong here?
Matter of factly, the whole getter/setter-mamboo-jamboo is nothing but a
pathetic attempt to overcome the lack of attribute-access-hooks, as they
are e.g. provided by python or C#.

By forcing this convention upon the programmer (and supporting it using
e.g. BeanInfo and other introspection-based mechanisms), Java allows for
the implementation of delegation, lazyness and so forth without all that
forcing major interface changes upon the user. Talking of interfaces -
they do lack properties as well... so you _can't_ possibly provide an
interface with attributes.


But I really don't think one can argue over a more aesthetic &
expressive syntax like

a.foo = b.bar * c.baz

compared to

a.setFoo(b.getBar() * c.getBaz())


Diez
 
B

Bruno Desthuilliers

Stargaming a écrit :
On Thu, 11 Oct 2007 18:58:44 +0200, Bruno Desthuilliers wrote:
[snip]

Your implementation seems particularly broken. You do not return anything
from `name()`,

Oops, my bad ! Indeed, I forgot the 'return property(**locals())' at the
end. And a couple other things too:
I'm going to point out a few other mistakes first:
(snip other corrections)

I'll call you when I'll have code to fix - you're doing a good job !-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,281
Latest member
Pedroaciny

Latest Threads

Top