John Posner wrote:
Matthew Woodcraft said:
I doubt it's because anyone particularly wanted this
behaviour; it just
falls out of the way '+=' is defined.
At the point where 'inst.x += 1' is compiled,
Python doesn't know
whether 'inst.x' is going to turn out to be a class
attribute or an
instance attribute or a property. So really the only thing
it can do is
generate code to read inst.x in the usual way and then
assign to inst.x
in the usual way (where 'the usual way' for CPython
is LOAD_ATTR and
STORE_ATTR).
That sounds reasonable to me.
Matthew Woodcraft also said:
Is there any actual advantage to self.attribute picking up
Class.attribute instead of raising a NameError?
You use that any time you call an ordinary method using syntax like
'self.foo()'.
Yes, but that's performing a read (and call) operation on an attribute. My
question concerned itself with potential confusion when you perform a write
operation on an attribute.
Bruno Desthuilliers said:
My question is ... WHY does the interpreter silently create the
instance attribute at this point,
Becaause that's how you create instance attributes in Python. Why do you
think 'self' - that is, a reference to some object - is mandatory in
"methods" (really, functions) arguments list ?
Or do you mean that the existence of a synonym class attribute should be
checked on each instance variable assignement ? This would probably be a
big performance hit, ...
Yes, Bruno, I'm persuaded by this argument. Ideally, I'd like the interpreter
to prevent the programmer from shooting him/herself in the foot, but it's not
worth the performance hit.
and it would make per-instance method overloading
impossible (remember that OOP is about objects, not classes).
Yes again. While I was writing the above comment ("write operation on an
attribute"), it *did* cross my mind that you might want to write self.attribute,
even if it names a method, not a data-item.
Summary: I no longer suspect that "Python is broken". I *do* think that there's
a situation that is potentially quite confusing:
* In the statement "self.x = self.x + 1", the two "self.x" names can sometimes
refer to different objects.
* Even worse, in the equivalent statement "self.x += 1", the single name
"self.x" can sometimes refer to two different objects!
I think this situation should be handled in documentation. (I'm a tech writer
in my day job ... oh wait, I forgot ... I got laid off from my day job in
December.) I'll look into what the standard Python doc set says on this matter.
What's broken here is trying to have a class variable and an instance
variable of the same name and expecting Python to get it right.
Both of these problems become non-issues if you follow the "best
practice" for defining instance variables:
That is, set instance variables to their initial value in the __init__
method. And if you need a class default value, name it differently:
For example:
class C:
default_x = 123
def __init__(self):
self.x = self.default_x
def inc(self):
self.x += 1 // behaves as expected
Then self.x or inst=C() and inst.x will always refer to a instance
variable, the code is clear, and no confusion ensues.
Gary Herron
-John
--
http://mail.python.org/mailman/listinfo/python-list
--
http://mail.python.org/mailman/listinfo/python-list