Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does initializing a variable via a python default variable keep state across object instantiation?

I hit an interesting python bug today in which instantiating a class repeatedly appears to be holding state. In later instantiation calls the variable is already defined.

I boiled down the issue into the following class/shell interaction. I realize that this is not the best way to initialize a class variable, but it sure should not be behaving like this. Is this a true bug or is this a "feature"? :D

tester.py:

class Tester():
        def __init__(self):
                self.mydict = self.test()

        def test(self,out={}):
                key = "key"
                for i in ['a','b','c','d']:
                        if key in out:
                                out[key] += ','+i
                        else:   
                                out[key] = i 
                return out

Python prompt:

Python 2.6.6 (r266:84292, Oct  6 2010, 00:44:09) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
>>> import tester
>>> t = tester.Tester()
>>> print t.mydict
{'key': 'a,b,c,d'}
>>> t2 = tester.Tester()
>>> print t2.mydict
{'key': 'a,b,c,d,a,b,c,d'}
like image 486
cbrinker Avatar asked Oct 08 '10 01:10

cbrinker


People also ask

What does initializing a variable mean in Python?

As soon as we set a variable equal to a value, we initialize or create that variable. Once we have done that, we are set to use the variable instead of the value. In Python, variables do not need explicit declaration prior to use like some programming languages; you can start using the variable right away.

Does Python automatically initialize variables?

For Python 3.7+ you can use a Data Class, which is a very pythonic and maintainable way to do what you want. It allows you to define fields for your class, which are your automatically initialized instance variables.

Should all member variables be initialized in __ init __?

If the value is not arbitrary and simply a default value that can be changed you should be using a default value in the __init__ method that can be overridden. It can also actually be a valid initial state, which is also not arbitrary and you should set it in the __init__ method.

Can we pass arguments to class in Python?

A function can take multiple arguments, these arguments can be objects, variables(of same or different data types) and functions. Python functions are first class objects. In the example below, a function is assigned to a variable.


1 Answers

It is a feature that pretty much all Python users run into once or twice. The main usage is for caches and the like to avoid repetitive lengthy calculations (simple memoizing, really), although I am sure people have found other uses for it.

The reason for this is that the def statement only gets executed once, which is when the function is defined. Thus the initializer value only gets created once. For a reference type (as opposed to an immutable type which cannot change) like a list or a dictionary, this ends up as a visible and surprising pitfall, whereas for value types, it goes unnoticed.

Usually, people work around it like this:

def test(a=None):
    if a is None:
        a = {}
    # ... etc.
like image 142
Stigma Avatar answered Sep 23 '22 12:09

Stigma