Python default arguments are not initialized on every call

I was writing code in Python and thought "Is it really?"

def wrap_list(value, base_list = []):
    base_list.append(value)
    return base_list

Suppose you have a code like this. If you call this many times, omitting the second argument:

print(wrap_list(1)) # => [1]
print(wrap_list(2)) # => [1, 2]

The result is. I want it to be [2] the second time.

If you try to display the object ID with the ʻid` function, you can see what happens.

def wrap_list(value, base_list = []):
    print(id(base_list)) # debug print
    base_list.append(value)
    return base_list

wrap_list(1) # => 4373211008
wrap_list(2) # => 4373211008

The object ID of base_list is the same in both calls. This means that an empty list is not generated for each call, but only once.

By the way, I also tried it in Ruby:

def wrap_list(value, base_list = [])
  puts base_list.object_id
  base_list << value
end

wrap_list(1) # => 70218064569220
wrap_list(2) # => 70218064588580

This seems to be generated for each call.

I don't think I would write code like the one above in Python:

class WrappedList(object):
    def __init__(self, initial = []):
        self.list = initial

    def append(self, value):
        self.list.append(value)

Of course, the same thing happens in such cases, so you need to be careful.

The fundamental problem is that "it is not initialized for each call", and the workaround is "do not perform destructive operations". If you need a destructive operation, you can set the default argument itself to None, and if it is None, initialize it with an empty list, and so on.

Recommended Posts

Python default arguments are not initialized on every call
Python and pip commands are not available on CentOS (RHEL) 8
a () and a.__ call__ () are not equivalent
Build Python environment on Ubuntu (when pip is not the default)
Call C / C ++ from Python on Mac
All Python arguments are passed by reference
Virtualenv does not work on Python3.5 (Windows)
Jinja2 2.9.6 does not work on Lambda Python 3 series
When will the default arguments be bound in python? When variables are bound in closure lazy evaluation.