开发者

Python: Dictionary as instance variable [duplicate]

This question already has answers here: Closed 11 years ago.

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.开发者_StackOverflow社区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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜