1

The reference count drops to zero after the function returns if no object is passed as the keyword argument, so shouldn't it be destroyed? If I am wrong in this assumption (and it drops to zero only in a practical sense) then I am curious, how/where is the reference hiding?

The scenario: declaring a function in Python 2.7 with at least one optional keyword argument, and that variable (the argument) is modified within the scope of the function. The very first call to the function does not specify the keyword argument (and thus it acquires the default value at the top level of recursion). The modified variable then becomes the default value in subsequent calls to the function.

Example: The following Python code raises an AssertionError on the last line:

closes = {'}':'{',']':'[',')':'('}

def vbr(string,i=0,braces=[]):
    global closes
    print string,i,braces
    if i==len(string):
        return len(braces)==0
    if string[i] in ['{','[','(']:
        braces.append(string[i])
        return vbr(string,i+1,braces)
    elif len(braces)>0 and closes[string[i]] == braces[-1]:
        braces.pop()
        return vbr(string,i+1,braces)
    else:
        return False

assert(vbr('([])()'))
assert(not vbr('([])({)'))
assert(vbr('([])()'))
  • 1
    I know it doesn't look like a duplicate, but the fact is: it's just because the default argument for the first call and the default for the second call are the same object. – zondo May 17 '16 at 14:10

1 Answers1

1

The function for which they are a default argument retains a reference to them, fixed at import-time. This is why using mutable default arguments is discouraged. Instead, use a default value of None and test the value at the start of your function.

mobiusklein
  • 1,403
  • 9
  • 12