First of all, I understand that I can use global
statement to access global variables. But somehow I was able to modify a global list without global
like below:
def func1(nums):
nums = [4,5,6]
nums = [1,2,3]
func1(nums)
print nums # print [1,2,3]
def func2(nums):
nums[0] = 4
nums[1] = 5
nums[2] = 6
nums = [1,2,3]
func2(nums)
print nums # print [4,5,6]
After trying func2, I realized that I can always access global list in a function if I specify the index:
def func3(nums):
nums[:] = [4,5,6]
nums = [1,2,3]
func3(nums)
print nums # print [4,5,6]
Is it because Python automatically go trying to match a global variable if a function variable is used before definition?
You can always access a global variable as long as you don't have a local variable of the same name. You only need the global statement when you are going to change what object a variable name refers to. In your func2 , you are not doing that; you are only changing the contents of the object.
Because lists and dictionaries are mutable, changing them (even inside a function) changes the list or dictionary itself, which isn't the case for immutable data types.
In other words, variables that are declared outside of a function are known as global variables. You can access global variables in Python both inside and outside the function.
I understand that I can use global statement to access global variables
Your understanding is wrong. You can always access a global variable as long as you don't have a local variable of the same name. You only need the global
statement when you are going to change what object a variable name refers to. In your func2
, you are not doing that; you are only changing the contents of the object. nums
still refers to the same list.
It is of concept based on mutable and immutable objects in Python. In your case, for example:
a=[1,2]
def myfn():
a=[3,4]
print id(a)
>>>id(a)
3065250924L
>>>myfn()
3055359596
It is clear both are different objects. Now:
a=[1,2]
def myfn():
a[:] =[3,4]
print id(a)
>>>id(a)
3055358572
>>>myfn()
3055358572
That means it is same variable using in local and global scope.
In this specific case it is because list
s are mutable.
As a result having them in the global namespace, or even passed through a function, means that they will be changed as Python holds the reference to the mutable object, not a copy of it.
If you try the same thing with tuple
s it will not work, as they are immutable.
The way to avoid this is to provide a copy of the list to the function, not the list itself:
func2(list[:])
At the same time you can do this with default arguments, where you can specify a default argument to be []
, and if you then .append()
something to it, that default argument will forever hold that item within it for all future calls (unless you remove it in some way).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With