globals(), locals(), vars() do not work as expected in a function of python
Question:
if I run one of following code variants
var1, var2 ='', ''
globals()['var1']='value1'
print(f'{var1=}, {var2=}')
var1, var2 ='', ''
locals()['var1']='value1'
print(f'{var1=}, {var2=}')
var1, var2 ='', ''
vars()['var1']='value1'
print(f'{var1=}, {var2=}')
all of them will return var1='value1', var2=''
, which is what I expect, but if I put them into a function, then they will not work any more.
def test():
var1, var2 ='', ''
globals()['var1']='value1'
return var1, var2
def test():
var1, var2 ='', ''
locals()['var1']='value1'
return var1, var2
def test():
var1, var2 ='', ''
vars()['var1']='value1'
return var1, var2
will return ('', '')
,any clue about makeing it also work in a function? thanks.
edit: thank to the link above, using globals(), locals(), vars() are often not good idea since locals() and vars() are immutable. For similar purposes, use a dict instead:
def test():
p = {'var1':'', 'var2':''}
p['var1']='value1'
return p['var1'], p['var2']
Answers:
Mutating globals()
is probably a bad idea, but to answer the question as asked, it is because assigning to names inside functions marks them as local variables by default. They then shadow the global variable of the same name if it exists. You can use a global
declaration to mark them as global variables.
Example:
var1 = 'this is a global variable'
var2 = 'this is also a global variable'
print(var1, var2)
def example():
global var2
var1 = 'this is a local variable'
var2 = 'this is still a global variable'
print(var1, var2)
example()
print(var1, var2)
So to get your desired behaviour, you should do:
def test():
global var1, var2
var1, var2 = '', ''
globals()['var1']='asdf'
return var1, var2
But in practice you should avoid mutating globals()
— and avoid re-assigning global variables in general.
if I run one of following code variants
var1, var2 ='', ''
globals()['var1']='value1'
print(f'{var1=}, {var2=}')
var1, var2 ='', ''
locals()['var1']='value1'
print(f'{var1=}, {var2=}')
var1, var2 ='', ''
vars()['var1']='value1'
print(f'{var1=}, {var2=}')
all of them will return var1='value1', var2=''
, which is what I expect, but if I put them into a function, then they will not work any more.
def test():
var1, var2 ='', ''
globals()['var1']='value1'
return var1, var2
def test():
var1, var2 ='', ''
locals()['var1']='value1'
return var1, var2
def test():
var1, var2 ='', ''
vars()['var1']='value1'
return var1, var2
will return ('', '')
,any clue about makeing it also work in a function? thanks.
edit: thank to the link above, using globals(), locals(), vars() are often not good idea since locals() and vars() are immutable. For similar purposes, use a dict instead:
def test():
p = {'var1':'', 'var2':''}
p['var1']='value1'
return p['var1'], p['var2']
Mutating globals()
is probably a bad idea, but to answer the question as asked, it is because assigning to names inside functions marks them as local variables by default. They then shadow the global variable of the same name if it exists. You can use a global
declaration to mark them as global variables.
Example:
var1 = 'this is a global variable'
var2 = 'this is also a global variable'
print(var1, var2)
def example():
global var2
var1 = 'this is a local variable'
var2 = 'this is still a global variable'
print(var1, var2)
example()
print(var1, var2)
So to get your desired behaviour, you should do:
def test():
global var1, var2
var1, var2 = '', ''
globals()['var1']='asdf'
return var1, var2
But in practice you should avoid mutating globals()
— and avoid re-assigning global variables in general.