Class Variable Access and Assignment

Steven D'Aprano steve at REMOVETHIScyber.com.au
Thu Nov 3 05:15:12 EST 2005


On Thu, 03 Nov 2005 01:43:32 -0800, Graham wrote:

[snip]

>     print instance_b.var # -> 5
>     print _class.var # -> 5
> 
> </code>
> 
> Initially this seems to make sense, note the difference between to last
> two lines, one is refering to the class variable 'var' via the class
> while the other refers to it via an instance.

That's not correct. The line instance_b.var is referring to an instance
attribute. According to the usual Object Oriented model of inheritance, if
the instance does not have an attribute, the class is searched next.

So instance_b.var and _class.var are asking for two different things. The
first says, "Search the instance for attribute var, then the class." The
second says "Search the class."

BTW, a leading underscore is the convention for a private(ish) variable.
The convention for naming a variable after a reserved word is a trailing
underscore class_. In this case, there is also the convention that classes
should start with a capital, so you have Class and instance. (instance, of
course, is not a reserved word.)


> However if one attempts the following:
> 
> <code>
> 
>     instance_b.var = 1000 # -> _class.var = 5
>     _class.var = 9999 # -> _class.var = 9999
> 
> </code>
> 
> An obvious error occurs. 

I see no error. No exception is raised when I try it: I get the expected
results. Assigning to an instance assigns to the instance, assigning to
the class assigns to the class. That's normal OO behaviour.


> When attempting to assign the class variable
> via the instance it instead creates a new entry in that instance's
> __dict__ and gives it the value. 

You might *want* to assign to the class attribute, but that's not what you
are doing. You are assigning to the instance.

Admittedly, it might not be the behaviour you expect, but it is the
standard behaviour in (as far as I know) all OO languages.

If you want to assign to the class attribute, you either assign to the
class directly, or use instance_b.__class__.var.


> While this is allowed because of
> pythons ability to dynamically add attributes to a instance however it
> seems incorrect to have different behavior for different operations.

Surely you can't mean that? Why would you want different operations to
have the same behaviour?


> There are two possible fixes, either by prohibiting instance variables
> with the same name as class variables, which would allow any reference
> to an instance of the class assign/read the value of the variable. Or
> to only allow class variables to be accessed via the class name itself.

There is also a third fix: understand Python's OO model, especially
inheritance, so that normal behaviour no longer surprises you.


-- 
Steven.




More information about the Python-list mailing list