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