Python: dictionary as instance variable

Possible duplicate:
Least Surprise in Python: Argument Argument Resolved by Argument

I am very confused by the behavior of dictionaries as instance variables of a class in Python 3. As I understand it, instance variables in Python have storage on each instance, unlike class variables that belong to the class (similar to what some other languages ​​call "static") .

And this seems to be true, unless the instance variable is a dictionary created from the default parameter. For instance:

class Foo: def __init__(self, values = dict()): self.values = values f1 = Foo() f1.values["hello"] = "world" f2 = Foo() print(f2.values) 

This program displays:

 {'hello': 'world'} 

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

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

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

But I do not understand why this should matter.

+6
source share
2 answers

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

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

 if values is None: self.values = {} else: self.values = values 
+10
source

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

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

If you specify values , this will be used. If not, values evaluates to FALSE the or operator and creates a new dict.

+2
source

Source: https://habr.com/ru/post/888244/


All Articles