Instance variables question

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Apr 16 20:52:30 EDT 2018


On Mon, 16 Apr 2018 09:03:47 -0700, Irv Kalb wrote:

> I have been writing OOP code for many years in other languages and for
> the past few years in Python.  I am writing new curriculum for a course
> on OOP in Python.


If you're going to be teaching Python, please don't teach terminology 
which is ambiguous and non-standard in the Python community.

The terminology we use is class and instance ATTRIBUTE, not "variable". 
The name is reflected in Python built-in functions getattr, setattr, 
delattr, as well as special dunder methods. While there are certain 
similarities, attributes and variables are quite different kinds of 
entities.

The syntax, semantics and implementation of variable and attribute access 
are different:

Syntax:

- variable access: uses bare names like `foo`

- attribute access: uses the dot pseudo-operator following almost
  any expression, such as `(result or calculation() + 1).attribute`

Semantics:

- variables are named values associated with a calculation; they are
  looked up across a relatively simple model involving a set of fixed
  scopes: locals, nonlocals (nested functions), globals, builtins

- attributes are intended as an abstraction of components of objects,
  for example dog.tail, car.engine, page.margins, etc, and are looked
  up by a much more complex model involving not just object inheritance
  but also the so-called "descriptor protocol"; unlike variables,
  attributes can also be computed on need

Implementation:

- variables are generally name/value pairs in a dictionary namespace,
  but in CPython at least, local variables are implemented using a
  faster table implementation

- attributes are also generally name/value pairs in a dictionary
  namespace, but they can also be computed at need using the
  special dunder methods __getattr__ and __getattribute__ or the
  property decorator


Additionally, the terms "class variable" and "instance variable" are 
ambiguous in Python, because classes and instances are first-class (pun 
not intended) values in Python. In the same way that people can talk 
about a variable intended to hold a string as a string variable, or one 
holding a float as a float variable, so we can talk about a variable 
intended to hold a class (or type) as a "class variable".

for s in ("hello", "world"):
    print("s is a string variable:", repr(s))

for t in (list, tuple, set, frozenset):
    print("t is a class variable:", repr(t))



[...]
> But there is something there that seems odd.  My understanding is that
> the "x = 0" would be defining a class variable, that can be shared by
> all PartyAnimal objects.  But he explains that because x is defined
> between the class statement and the "party" method, that this defines an
> instance variable x.   That way, it can be used in the first line of the
> "party" method as self.x to increment itself.

Indeed. Unlike some languages like Java, attributes are looked up at 
runtime, and instance attributes may shadow class attributes of the same 
name.

If you want to assign to a class attribute, rather than writing

    self.x = value


you need to specify that you're writing to the class:

    type(self).x = value



-- 
Steve



More information about the Python-list mailing list