Python's handling of default parameter values is one of a few things, tends to trips up most new Python programmers (BU T usually only once).
What causes the confusion are the behaviour you get if you use a "mutable" object as a default value; That's, a value, can be modified, and a list or a dictionary.
An example:
>>> def function(data=[]):... data.append(1)... return data...>>> function()[1]>>> function()[1, 1]>>> function()[1, 1, 1]
As can see, the list keeps getting longer and longer. If you are in the list identity, you'll see that the function keeps returning the same object:
>>> ID (function ()) 12516768>>> ID (function ()) 12516768>>> ID (function ()) 12516768
The reason is simple:the function keeps using the same object with each call. The modifications we make is "sticky".
Why does this happen? #
Default parameter values evaluated when, and only when, the ' def ' statement they belong to is executed ; See
http://docs.python.org/ref/function.html (Dead link)
For the relevant sections in the Language Reference.
Also Note that "Def" is a executable statement in Python, and that default arguments be evaluated in the "DEF" statement ' s environment. If you execute the "def" multiple times, it ' ll create a new function object (with freshly calculated default values) each time . We ' ll see examples of this below.
What does instead? #
The workaround is, as others has mentioned, to use a placeholder value instead of modifying the default value. None is a common value:
def myfunc(value=None): if value is None: value = [] # modify value here
If you need to handle arbitrary objects (including None), you can use a Sentinel object:
sentinel = object()def myfunc(value=sentinel): if value is sentinel: value = expression # use/modify value here
In older code, written before "object" is introduced, you sometimes see things like
Sentinel = [' placeholder ']
Used to create a Non-false object with a unique identity; [] Creates a new list every time it is evaluated.
Valid uses for mutable defaults #
Finally, it should is noted that the advanced Python code often uses this mechanism to its advantage; For example, if you create a bunch the UI buttons in a loop, you might try something like:
In range: callback (): "clicked Button", I UI. Button ("button%s"% i, callback)
Callbacks Print the same value (most likely 9, in this case). The reason for this was that Python's nested scopes bind to variables, not object values, so all callback instance s would see the current (=last) value of the "I" variable. To fix the, use explicit binding:
In range: Callback (i=i): "clicked Button", I UI. Button ("button%s"% i, callback)
The "i=i" part binds the parameter "I" (a local variable) to the current value of the outer variable "I".
The other uses is local caches/memoization; e.g.
(It happened to me in one of the first Python programs I ever wrote, and it took several years before we spotted the (non- Critical) bug, when someone looked a bit more carefully on the contents of a property file, and wondered what's all those th Ings were doing there ...)
Calculate (A, B, C, memo={}): Try: # return already calculated value except Keyerror: value = Heavy_calculation (A, B, c) return value
(This was especially nice for certain kinds of recursive algorithms)
And, for highly optimized code, local rebinding of global names:
Import Maththis_one_must_be_fast (x, Sin=math.sin, Cos=math.cos): ...
How does this work, in detail? #
When Python executes a "DEF" statement, it takes some ready-made pieces (including the compiled code for the function body and the current namespace), and creates a new function object. When it does this, it also evaluates the default values.
The various components is available as attributes on the function object; Using the function we used above:
>>> function.func_name"<stdin>", line 1>>>> function.func_defaults ([1, 1, 1],) >>> function.func_globals{' function ': <function function at 0x00bf1c30>,' __builtin__ ' (built- in),' __doc__ ': None}
Since You can access the defaults, you can also modify them:
>>> function.func_defaults[0][:] = []>>> function () [1]>>> function.func_defaults ([1],)
However exactly something I ' d recommend for regular use ...
Another to reset the defaults are to simply re-execute the same "DEF" statement. Python would then create a new binding to the code object, evaluate the defaults, and assign the function object to the SAM e variable as before. But again, the only doing if you know exactly "What are you ' re doing.
And yes, if you happen to has the pieces but not the function, you can use thefunction class in the new Module to create your own function object.
Default Parameter Values in Python