Instance vs Class variable oddity

Ben Finney ben+python at benfinney.id.au
Wed May 15 20:41:47 EDT 2019


Irv Kalb <Irv at furrypants.com> writes:

> I just saw some code that confused me.  The confusion has to do with
> class variables and instance variables.

(Perhaps unrelated, but here's another confusion you may be suffering
from: There's no such thing as a “class variable” or “instance
variable”. In Python, a “variable” is always a *binding* between a name
and and object. The “variable” has no concept of different types.)

> When I instantiate two objects (t1 and t2), the __init__ method calls
> the show method, which prints a value of self.x.

That's right. The ‘__init__’ method initialises an already-created
instance, and so has the same access any other instance method has.

> I'm not understanding why this is legal.  I would expect that I would
> get an error message saying that self.x does not exist, since no
> instance variable named self.x has been defined.

Note that you're not calling the initialiser (‘__init__’) directly.

Also note that the initialiser receives, as its first argument, the
already-existing instance. So something has already created that
instance before calling the initialiser.

The initialiser ‘__init__’ is called from the constructor (‘__new__’),
and this happens only *after the instance is created*. For details see
<URL:https://docs.python.org/3/reference/datamodel.html#object.__new__>
the documentation for the constructor method, ‘__new__’.

> My guess is that there is some scoping rule that says that if there is
> no instance variable by a given name, then see if there is one in the
> class.

Yes, though that is an entirely separate issue from when the initialiser
gets called.

You are correct that the scope resolution includes:

* Does the attribute exist on this instance?
* Does the attribute exist on this instance's class?

and it continues with the class's superclass(es), and so on until it
finds an attribute with that name.

> If the self.x on the right hand side refers to the class variable

For the purpose of resolving the value of the right hand side, yes.

> and creates an instance variable called self.x on the left hand side

Yes.

(The correct terms are “class attribute” and “instance attribute”.)

> then how does the second call work using the value of the instance
> variable on the right hand side?

I'm not sure I understand the confusion; once the instance has an
attribute of that name, the same logic you outlined above applies when
attempting to resolve that attribute. When ‘self.x’ exists on the
instance, that's what will be used when resolving ‘self.x’.

I hope that helps.

-- 
 \        “To me, boxing is like a ballet, except there's no music, no |
  `\       choreography, and the dancers hit each other.” —Jack Handey |
_o__)                                                                  |
Ben Finney




More information about the Python-list mailing list