Python: Dictionary as instance variable [duplicate]
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.
精彩评论