Class Variable Access and Assignment

Antoon Pardon apardon at forel.vub.ac.be
Fri Nov 4 10:03:56 CET 2005


Op 2005-11-03, Steven D'Aprano schreef <steve at REMOVETHIScyber.com.au>:
> On Thu, 03 Nov 2005 13:01:40 +0000, Antoon Pardon wrote:
>
>>> Seems perfectly sane to me. 
>>>
>>> What would you expect to get if you wrote b.a = b.a + 2?
>> 
>> I would expect a result consistent with the fact that both times
>> b.a would refer to the same object.
>
> class RedList(list):
>     colour = "red"
>
> L = RedList(())
>
> What behaviour would you expect from len(L), given that L doesn't have a
> __len__ attribute?

Since AFAICT there is no single reference to the __len__ attribute that
will be resolved to two different namespace I don't see the relevance.

>>> Why do you expect
>>> b.a += 2 to give a different result?
>> 
>> I didn't know I did.
>
> It seems to me that you do.
>
> You didn't appear to be objecting to a line like x = b.a assigning the
> value of 1 to x (although perhaps you do). If that was the case, then it
> is perfectly reasonable to expect b.a = x + 2 to store 3 into b.a, while
> leaving b.__class__.a untouched.
>
> Of course, if you object to inheritance, then you will object to x = b.a
> as well.

What I object to is that the mentioning of one instance gets resolved
to two different namespaces.

>>> Since ints are immutable objects, you shouldn't expect the value of b.a
>>> to be modified in place, and so there is an assignment to b.a, not A.a.
>> 
>> You are now talking implementation details. I don't care about whatever
>> explanation you give in terms of implementation details. I don't think
>> it is sane that in a language multiple occurence of something like b.a
>> in the same line can refer to different objects
>
> That's an implementation detail only in the sense that "while condition"
> is a loop is an implementation detail. It is a *design* detail.

> b is a name, and any reference to b (in the same namespace) will refer
> to the same object. At least until you rebind it to another object.

But some namespaces take great care not to allow a rebinding that would
result in the same name being resolved to a different namespace during
this namespace's lifetime.

> But b.a is not a name, it is an attribute lookup,

An other implementation detail. b.a is a name search of 'a' in the
namespace b.

> and by Python's rules of
> inheritance that lookup will look up attributes in the instance, the
> class, and finally any superclasses.

> If you persist in thinking of b.a as a name referring to a single object,
> of course you will be confused by the behaviour. But that's not what
> attribute lookup does.

> On the right hand side of an assignment, it will return the first existing
> of b.__dict__['a'] or b.__class__.__dict__['a']. On the left hand of an
> assignment, it will store into b.__dict__['a'].

That holly python does it this way, doesn't imply it is reasonable to
do it this way or that all consequences of doing it this way are
reasonable.

>> I think it even less sane, if the same occurce of b.a refers to two
>> different objects, like in b.a += 2
>
> Then it seems to me you have some serious design problems. Which would you
> prefer to happen?
>
> # Scenario 1
> # imaginary pseudo-Python code with no inheritance:
> class Paragraph:
>     ls = '\n'  # line separator
>
> para = Paragraph()
> para.ls
>
>=> AttributeError - instance has no attribute 'ls'
>
>
> # Scenario 2
> # imaginary pseudo-Python code with special inheritance:
> class Paragraph:
>     ls = '\n'  # line separator
>
> linux_para = Paragraph()
> windows_para = Paragraph()
> windows_para.ls = '\n\r'  # magically assigns to the class attribute
> linux_para.ls
>
>=> prints '\n\r'
>
> # Scenario 3
> # Python code with standard inheritance:
> class Paragraph:
>     ls = '\n'  # line separator
>
> linux_para = Paragraph()
> windows_para = Paragraph()
> windows_para.ls = '\n\r'
> linux_para.ls
>
>=> prints '\n'
>

I don't see the relevance of these pieces of code. In none of them is
there an occurence of an attribute lookup of the same attribute that resolves
to different namespaces.

-- 
Antoon Pardon



More information about the Python-list mailing list