Antoon Pardon wrote: > Op 2005-11-03, Stefan Arentz schreef <[EMAIL PROTECTED]>: > >>Antoon Pardon <[EMAIL PROTECTED]> writes: >> >>... >> >> >>>>>No matter wat the OO model is, I don't think the following code >>>>>exhibits sane behaviour: >>>>> >>>>>class A: >>>>> a = 1 >>>>> >>>>>b = A() >>>>>b.a += 2 >>>>>print b.a >>>>>print A.a >>>>> >>>>>Which results in >>>>> >>>>>3 >>>>>1 >>>> >>>>I find it confusing at first, but I do understand what happens :-) >>> >>>I understand what happens too, that doesn't make it sane behaviour. >>> >>> >>>>But really, what should be done different here? >>> >>>I don't care what should be different. But a line with only one >>>referent to an object in it, shouldn't be referring to two different >>>objects. >> >>It doesn't. > > > Yes it does. If the b.a refers to the instance variable, then an > AttributeError should be raised, because the instance variable doesn't > exist yet, so you can't add two to it. > Excuse me. The statement
a += 2 causes a to refer to a different object after the assignment than it did before. So does the statement self.a += 2 So why are you so concerned that the pre-assignment reference comes from a different scope to the post-assignment reference? The fact remains that after both assignments the rebound name can no longer (ever) be used to refer to its former referent without a further rebinding taking place. > If the b.a refers to the class variable then two should be added to it. > Wring, wring, wring. (Sorry, got that wrong :-) > Neither happens instead we get some hybrid in which an instance varible > is created that gets the value of class variable incrented by two. > Yes. So does this mean you also have a problem with def f(x): x += 2 g = 3 print f(g) When the function call executes, the name x is bound to an object in the call's containing scope. Is it then your contention that the augmented assignment in the function should add two to that object, changing the value of g? For extra marks please explain the difference between augmented assignment to a function argument and augmented assignment to a class variable referenced through self. > >>>In the line: b.a += 2, the b.a should be refering to the class variable >>>or the object variable but not both. So either it could raise an >>>attribute error or add two to the class variable. >> I'm not sure where this moral imperative comes from, and your arguments singularly fail to convince me. >>It does exactly what you say. It adds 2 to the a *instance variable* of >>the object instance in 'b'. > > > There is no instance variable at that point. How can it add 2, to > something that doesn't exist at the moment. > It doesn't, it simply proceeds along the lines of all Python assignments and resolves the name as a reference to a specific object. It then computes a new value from the referenced object and the augmented assignment operator's right operand, and rebinds the name to the newly-computed value. Please stop talking about variables. Although augmented assignment operators have the *option* of updating objects in place, surely not even you can require that they do so when they are bound to an immutable object such as an integer. > >>It doesn't touch the *class variable* A.a which is still 1. > Why "should" it? Why, why, why? And gain, just for good measure, why? Augmented assignment to a function argument doesn't modify the passed object when immutable, and you have no problem with that (I know as I write that this is just asking for trouble, and it will turn out that you also find that behavior deeply controversial ...) > > But it accesses the class variable. > Repeat after me: "Python assignment binds values to names". When I write class something: a = 1 def __init__(self, val=None): if val: self.a += val then in the last statement the augmented assignment rebinds "self.a" from the class "variable" to a newly-created instance "variable". I am of course using the word "variable" here in a Pythonic sense, rather than in the sense that, say, a C programmer would use. In Python I prefer to talk about binding names because talking of variables leads people to expect that a name is bound to an area of memory whose value is modified by assignment, but this is in fact not so. The initial access to self.a uses the defined name resolution order to locate a value that was bound to the name "a" in class scope. So what? This is a long-documented fact of Python life. It's *supposed* to be that way, dammit. I fail to understand why this is such a problem for you. But then it's clear from long past experience that our perceptions of Python's execution model differ quite radically, and that I seem to find it quite satisfactory overall, whereas you are forever banging on about what "should" be true of Python and what Python "should" do. Which, as is probably obvious by now, I sometimes find just a teeny bit irritating. Kindly pardon my tetchiness. I suppose ultimately I'm just more pragmatic than you. Plus I started using Icon, whose assignment semantics are very similar, back in the 1970's, so Python's way of doing things fits my brain quite nicely, thank you. regards Steve PS As a total non-sequitur added for light relief at the end of what seems even to me to be a slightly tedious post, I discover I managed to misspell "assignment" in four distinct ways during the composition of the above. -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC www.holdenweb.com PyCon TX 2006 www.python.org/pycon/ -- http://mail.python.org/mailman/listinfo/python-list