Python: Dictionary as instance variable

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

I'm very confused about the behavior of dictionaries as class instance variables in Python 3. The way I understand it, instance variables in Python have per-instance storage, unlike class variables which are per-class (similar to what some other languages call "static").

And this seems to hold true, except when the instance variable is a dictionary created from a default parameter. For example:

class Foo:
    def __init__(self, values = dict()):
        self.values = values

f1 = Foo()
f1.values["hello"] = "world"

f2 = Foo()
print(f2.values)

This program outputs:

{'hello': 'world'}

Huh? Why does the instance f2 have the same dictionary instance as f1 ?

I get the expected behavior if I don't pass in an empty dictionary as a default parameter, and just assign self.values to an empty dictionary explicitly:

class Foo:
    def __init__(self):
        self.values = dict()

But I can't see why this should make any difference.


This is a well known surprise in Python. The default parameters are evaluated when the function is defined, not when it is called. So your default parameter is a reference to a common dict . It has nothing to do with assigning it to class/instance variables.

If you want to use a default parameter, use None , and check it:

if values is None:
    self.values = {}
else:
    self.values = values

Default values are only evaluated once. You want something like this:

 class Foo:
     def __init__(self, values = None):
         self.values = values or dict()

If you supply a values , that'll get used. If not, values is evaluated as FALSE by the or operator and instantiates a new dict.

链接地址: http://www.djcxy.com/p/28532.html

上一篇: Python基类共享属性?

下一篇: Python:Dictionary作为实例变量