This question has already been answered:

I have a question on the default parameters of functions . That is, by

>>> def foo(my_list=[]): ... my_list.append(1) ... return my_list ... >>> foo() [1] >>> foo() [1, 1] >>> foo() [1, 1, 1] >>> 

I understand why this is happening (the question of the rationality of such behavior will be left outside)

Do I understand correctly that if I call a function once with such a default list, where to fill it with a gigabyte of data, return, use and then forget, then the memory will still be held due to the default [] pinned to def foo?

Marked as a duplicate by the participants Sergey Gornostaev , 0xdb , aleksandr barakin , Jarvis_J , Andrey NOP 12 Dec '18 at 4:43 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • If we consider a function as an object, then in theory a garbage collector can remove both the function itself and its associated memory (for example, in default parameters) after the last use of the function. How can it in fact - I can not say. - insolor
  • 2
    @insolor under normal conditions when a function is just a function or as a class method it is impossible to say when there will be a “last use”. Even if it is a class method and create a new object, then it continues to fumble all the same default variable tied to the method. That is, I do not see any options, except how not to use the default mutable parameters at all because they threaten with a memory leak, even with a single call - vitidev
  • Now I tried, it seems, really the memory itself does not return. Memory is freed only if you explicitly call del foo . - insolor
  • @SergeyGornostaev duplicate. there is little to be a duplicate - it is still necessary that the search is easy to find, and with this a duplicate has a big problem - vitidev

1 answer 1

The default argument is created once, in the place where the function foo is defined and stored in it, it is just an ordinary variable that you can access without calling foo ()

If you would create an immutable argument by default, the size of a gigabyte, it should not be reset when calling foo, that is its meaning, store the same data. So why should my_list be freed?

The difference being changed is an argument or not, in that when calling foo a new one will be created (if unchanged, for example tupple) my_list or the same is updated (if changed) my_list

you can reset it by deleting the foo object in which my_list is stored or resetting my_list itself

 def foo(my_list=[]): my_list.append(list(range(10))) return my_list print(foo.__defaults__) foo() print(foo.__defaults__) foo.__defaults__[0].clear() print(foo.__defaults__) ([],) ([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]],) ([],) 
  • > this is its meaning, store the same data. So why should my_list be freed? ... Because this is the expected behavior - to create a value if it is not transmitted. And that’s it! And certainly not to create a common "static" variable. The passed variables are local inside the function and created implicitly must be exactly the same - because the goal of default is the "optional parameter". I understand the reasons - they made the implementation simpler and in order to optimize the speed of work, but this is not expected (and in fact in other languages ​​there is no such biaki), but simply a “feature” specifically of a python. - vitidev
  • you need to read the differences between mutable and immutable, but yes - vadim vaduxa
  • I know how they differ, because it was unexpected for me in python (taking into account the python philosophy), it turns out that python solves the problem of optional arguments in its own way (or rather badly solves, because for the mutable you have to set = None and then manually create ) and instead of syntactic sugar, carefully laid out a rake which must be remembered. - vitidev
  • It seems to me that such an approach in python is everywhere, because even foo or print or clear are objects of classes that inherit from type. Those are created once, like the default arguments - vadim vaduxa
  • @vitidev: the data is not static: each function has its own data like all other objects in Python. If you understand that a function is an object and the default values ​​are calculated at the time the function is created, then the behavior becomes obvious. You are not surprised that the d = dict(a=[]) construction does not lead to the creation of new lists with each call: d['a'] ? (a list is created when a dictionary is created. d['a'] always refers to the same list, unless explicitly replaced). - jfs