[Tutor] Static Variable in Functions

Steven D'Aprano steve at pearwood.info
Mon Mar 14 04:21:46 CET 2011


Yaşar Arabacı wrote:

> Author of this post says that we can use mutable variables like this as 
> static function variables. I was wondering what are mutable variables 
> and what is rationale behind them.

It sounds like you are reading about Python with the mind-set of a C 
programmer. Python is not C. Python does not have variables in the same 
sense that C has. Python uses a different assignment model: instead of 
variables with a fixed type at a fixed memory location, Python's 
assignment model is that you have objects, and names in namespaces. The 
distinction is important because you can have names without objects, 
objects without names, and objects with more than one name.


A name without an object is a runtime error, not a compile-time error:

 >>> spam  # A name without an object
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined

But an object without a name is perfectly fine. Anonymous objects are 
very frequent in Python, so frequent that you've probably already used 
them without realising. This line creates four objects but only one name:

 >>> t = [42, 'ham and eggs', 1.5]

The name 't' is bound to the list object. The objects 42, 'ham and eggs' 
and 1.5 (an int, a str and a float) are anonymous -- they have no names. 
But you can give them names at any time:

 >>> breakfast = t[1]  # bind a name to the object in the list
 >>> n = len(breakfast)  # and pass it to a function

or you can continue to use them anonymously:

 >>> n = len(t[1])

It's not clear what "variable" would mean in Python unless it refers to 
the combination of a name bound to an object. I often use "variable" in 
that sense myself, but it's a bad habit, because it can confuse people 
who have an idea of what a variable is that is different from what 
Python does.

In Python, it is *objects* which are either mutable (changeable) or 
immutable (fixed), not names. All names are mutable in the sense that 
you can re-bind or delete them:

 >>> x = 12345  # the name x is bound to the object 12345
 >>> x = "two"  # and now the name is bound to a different object
 >>> del x  # and now the name x is gone

But the objects themselves are inherently either mutable or immutable, 
regardless of the name. You cannot change the mutability of the object 
by changing the assignment, only by using a different object. Consider 
lists and tuples, which are both sequences of objects, but lists are 
mutable and tuples are not:

 >>> items = [1, 2, 3]  # The list can be changed in place.
 >>> items[2] = 4
 >>> print(items)
[1, 2, 4]

So "the variable is mutable". But if we re-bind the name to a different 
object:

 >>> items = tuple(items)
 >>> print(items)
(1, 2, 4)
 >>> items[2] = 8
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

"the variable is immutable". Notice that it is the *object* that does 
not support item assignment. The *name* does not get a say about whether 
the object is mutable or not: the tuple will always be immutable, no 
matter what name it is bound to.

Most of the common built-in Python objects are immutable:

ints
floats
complex numbers
strings (both Unicode and byte strings)
tuples
bools (True and False)
None
frozensets

while a few are mutable:

lists
dicts
sets

Custom types created with the class statement are mutable, unless you 
take special efforts to make them immutable. For example, the Fraction 
class is written to be immutable:

 >>> from fractions import Fraction as F
 >>> f = F(1, 3)
 >>> f
Fraction(1, 3)
 >>> f.denominator
3
 >>> f.denominator = 5
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: can't set attribute



-- 
Steven



More information about the Tutor mailing list