Variables¶
Instance variables¶
In the previous example, length
is an instance variable of Square
instances, which means that each instance of the class Square
has its own
copy of length
, and the value stored in this copy may be different from the
values stored in the length
variable in other instances. In Python, you can
create instance variables as needed by assigning them to the field of a class
instance. If the variable does not already exist, it will be created
automatically.
All uses of instance variables, both assignment and access, require explicit
mention of the instance they contain, that is, instance.variable
. A
reference to a variable in itself is not a reference to an instance variable,
but to a local variable in the executing method. This is different from C++ and
Java, where instance variables are referenced in the same way as local function
variables of the method. Python requires explicit mention of the contained
instance here, and this enables a clear distinction between instance variables
and local function variables.
Class variables¶
A class variable is a variable associated with a class, not an instance of a class, that can be accessed by all instances of the class. A class variable can be used to store some class-level information, such as how many instances of the class were created at a particular time. Python provides class variables, although using them requires a little more effort than in most other languages. You also need to be aware of an interaction between class and instance variables.
A class variable is created by an assignment in the class, but outside the
__init__
function. After it is created, it can be seen by all instances of
the class. You can use a class variable to make a value for pi
accessible to
all instances of the Circle
class:
>>> class Circle:
... pi = 3.14159
... def __init__(self, diameter):
... self.diameter = diameter
... def circumference(self):
... return self.diameter * Circle.pi
...
Once you have entered this definition, you can query pi
with:
>>> Circle.pi
3.14159
Note
The class variable is linked to and contained within the class that defines
it. You access Circle.pi
in this example before any Circle
instances
have been created. It is obvious that Circle.pi
exists independently of
specific instances of the Circle
class.
You can also access a class variable from a method of a class using the class
name. You do this in the definition of Circle.circumference
, where the
circumference
function contains a special reference to Circle.pi
:
>>> c = Circle(3)
>>> c.circumference()
9.424769999999999
However, it is unpleasant that the class name Circle
is used in the
circumference
method to address the class variable pi
. You can avoid
this by using the special __class__
attribute, which is available for all
Python class instances. This attribute returns the class to which the instance
belongs, for example:
>>> Circle
<class '__main__.Circle'>
>>> c.__class__
<class '__main__.Circle'>
The Circle
class is internally represented by an abstract data structure,
and this data structure is exactly what is obtained by the __class__
attribute of c
, an instance of the Circle
class. In this example, you
can retrieve the value of Circle.pi
from c
without explicitly referring
to the name of the Circle
class:
>>> c.__class__.pi
3.14159
You can use this code internally in the circumference
method to get rid of
the explicit reference to the Circle
class; replace Circle.pi
with
self.__class__.pi
.
There is a little oddity about class variables that might confuse you if you are not aware of it.
Warning
If Python searches for an instance variable and does not find an instance variable with that name, it will search for and return the value in a class variable with the same name. Only if no matching class variable can be found does Python return an error. This can be used to efficiently implement default values for instance variables; however, this also easily leads to accidentally referring to an instance variable instead of a class variable without an error being reported.
First, you can refer to the variable c.pi
, even though c
has no
associated instance variable called pi
. Python first tries to find such
an instance variable and only when it cannot find an instance variable does
it look for a class variable pi
in Circle
:
>>> c1 = Circle(1)
>>> c1.pi
3.14159
If you now find that your specification for pi
has been rounded too
early and you want to replace it with a more precise specification, you
might be inclined to change it as follows:
>>> c1.pi = 3.141592653589793
>>> c1.pi
3.141592653589793
However, you have now only added a new instance variable pi
to c1
.
The class variable Circle.pi
and all other instances derived from it
still have only five decimal places:
>>> Circle.pi
3.14159
>>> c2 = Circle(2)
>>> c1.pi
3.14159