0

I've just discovered this weird thing where if I create a global variable called for example numbers and then call a function with a default variable with the same name it accesses that global variable even though it's not specifically passed in or referenced with the global operator. This seems like it shouldn't be possible. Is there a reason why this happens and is this explained anywhere in the Python documentation?

This example shows what I mean:

def append(number, numbers=[]):
    print(numbers)
    numbers.append(number)
    return numbers

numbers = append(1)
different_numbers = append(2)

print(numbers, 'end')

Output:

[]
[1]
[1, 2] end
Rob Kwasowski
  • 2,690
  • 3
  • 13
  • 32
  • See https://docs.python-guide.org/writing/gotchas/ – michaeldel May 22 '20 at 11:52
  • `numbers` isn't a global; your function has a parameter named `numbers` that exists whether or not you pass an argument. If you *don't* pass an argument, it uses a separate, function-specific list as its value, not the list bound to the global name `numbers`. – chepner May 22 '20 at 11:54

2 Answers2

1

Python lists store references ("pointers") to the objects.

You changing the actual list when you do that.

First your function creates a numbers variable that, prints an empty list, then returns a list to the numbers in your statement numbers = append(1)

Now there exists a numbers variable with a 1 in it, which is pointing to the numbers that was created by your function.

when you append(2), you first print what was already in the numbers variable that exists from your function, then you append 2 to it.

Finally you print the numbers that already exists.

You are in effect pointing to the same array in all 2 or 3 variables.

You can try using hex(id(x)) to find the location of the variable.

Try this

def append(number, numbers=[]):
    print(numbers)
    print(hex(id(numbers)))
    numbers.append(number)
    print(hex(id(numbers)))
    return numbers

numbers = append(1)
print (hex(id(numbers)))
different_numbers = append(2)

print(numbers, 'end')
print (hex(id(numbers)))
print (hex(id(different_numbers)))

You should get the same address for each line every time, but if you del numbers and del different_numbers after each run, you will change the address the array is stored at but it will be the same within each run.

anarchy
  • 3,709
  • 2
  • 16
  • 48
  • if you run the code more than once make sure you ```del numbers``` and ```del different_numbers``` – anarchy May 22 '20 at 12:12
0

If a variable with the same name is defined inside the scope of function as well then it will print the value given inside the function only and not the global value.

tanmayjain69
  • 158
  • 1
  • 10