我对使用python中的setdefault()时全局变量的行为感到有点困惑:
请使用setdefault查找有关如何引用/解析此示例的示例代码,有人可以帮我澄清这里发生了什么吗?
重置变量的主文件:
#main
from test import *
fill_func()
print my_list
print my_dict
为变量赋值的测试文件:
#test
my_list = []
my_dict = {}
def fill_func():
my_list = [1,2,3]
print my_list
my_dict.setdefault(0,[]).append('zero')
print my_dict
输出:
[1, 2, 3]
{0: ['zero']}
[]
{0: ['zero']}
我无法理解为什么list(my_list)变量在从main.py调用时显示为空,而my_dict显示数据正常?
感谢任何帮助。 TIA!
#示例测试文件2
#test
my_list = []
my_dict = {}
def fill_func():
def fill_list():
global my_list
my_list = [1,2,3]
print my_list
my_dict.setdefault(0,[]).append('zero')
print my_dict
fill_list()
输出:
{0: ['zero']}
[1, 2, 3]
[]
{0: ['zero']}
有人可以对第二个测试文件进行一些说明,请耐心等待,了解基础知识:)
TIA!
答案 0 :(得分:2)
my_list
被定义为fill_func
内的局部变量;这是在全局范围内定义的另一个my_list。
因此,您的代码首先调用打印本地fill_func
的{{1}},然后调用默认的dict。然后它退出函数并打印外部范围my_list
和字典(未被遮蔽)
答案 1 :(得分:1)
您正在创建一个与全局变量同名的局部变量。只需在函数顶部添加global my_list
即可。
答案 2 :(得分:1)
这是因为,正如你正确指出的那样,它与范围有关。 my_list
和my_dict
是test.py
的全局,必须使用global
限定符进行访问。也就是说,您的代码应为:
# Edited to address comments (see explanation below)
def fill_func():
global my_list # this is necessary since you're updating the values
global my_dict
my_list.extend([1,2,3])
print my_list
my_dict.setdefault(0,[]).append('zero')
print my_dict
编辑:
要获得要更新的列表和字典,必须扩展列表,并修改字典(正如您所做的那样) - 即实际更改其值。使用赋值运算符为其赋值只会更改变量引用的值而不是值本身。这就是为什么它不在本地函数范围之外更新的原因。而且,这也是我们使用其他方法修改这些变量内容时更新的原因。
问题在于解析函数体使用的所有变量 在正常分配或增加的分配中被视为 局部变量,所以当调用函数时,Python不会显示 对于全局范围内的变量,因此会引发错误。 因此,您需要将这些变量指定为全局,以告诉Python 在全球范围内寻找它们。
另一种方法是使用list.extend()
(从此处开始:https://stackoverflow.com/a/23436510/866930。对此有用的其他参考资料是:https://stackoverflow.com/a/31437415/866930)
只要您没有,您就可以随时访问全局变量 同名的局部变量。您只需要全局声明 当您要更改变量名称引用的对象时。
与此版本比较:
def fill_func():
global my_list
global my_dict
my_list = [1,2,3]
print my_list # prints `[1, 2, 3]` here and `[]` in main
my_dict = {1: 'a', 2: 'b'}
print my_dict # prints `{1: 'a', 2: 'b'}` here, and `{}` in main
如果不使用global
,Python会认为变量是定义它的代码元素范围的本地变量,因此global
告诉解释器查看globals
}符号表(可以通过globals()
)
答案 3 :(得分:0)
您需要在函数中声明要使用全局变量。
你可以通过
来做到这一点def fill_func():
global my_list
global my_dict
my_list = [1,2,3]
print my_list
my_dict.setdefault(0,[]).append('zero')
print my_dict
请注意,通常最好只使用大写字母来表示全局,以避免混淆