Class Variable Access and Assignment

Antoon Pardon apardon at forel.vub.ac.be
Fri Nov 4 04:58:20 EST 2005


Op 2005-11-04, Steve Holden schreef <steve at holdenweb.com>:
> Antoon Pardon wrote:
>> Op 2005-11-03, Stefan Arentz schreef <stefan.arentz at gmail.com>:
>> 
>>>Antoon Pardon <apardon at forel.vub.ac.be> 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

But the 'a' is both times in the same namespace.

>      self.a += 2

In this case the 'a' is not necessarily both times in the same
name space.

> 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.

I concerned with the a refering to different variables. A variable being
a name in a specific namespace.

>> 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?

Whether I have a problem with this specific behaviour or not is
irrelevant. In this case we have only one namespace with an 'x'.
So searching for 'x' will not result in different variables being
found.

> 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.

No I think variable is the right term here. It refers to a name
in a specific namespace.

> 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.

No but I can require that the namespace to which a name is resolved,
doesn't change during the operation.

>>>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".

But not just to a name, it binds a name in a specific namespace.

> 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.

That it is documented, doesn't make it sane behaviour. Otherwise
all companies had to do was to document there bugs.

In a line like b.a += 2, you only have one reference to a name
to be resolved in a spefied namespace (hierarchy). Since there
is only one reference I don't think it is sane that two resolutions
are done with two different variables as a result.

> 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.

It has nothing to do with being more pragmatic. Being pragmatic
is about how you handle things with real life projects. It has
little to do with the degree in which you agree with the design
of the tool you have to work with. I would say I am more pragmatic
than most defenders of python, because when it comes done to
do my work, I just use python as best as I can, while a lot
of people here seem to think that every little criticism I have
is enough to go and look for a different language.

> 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.

So, people can probably say that about any language they started with.
That a language suits a certain persons brain, may say more about
the person than about the language.

-- 
Antoon Pardon



More information about the Python-list mailing list