python中使用setdefault的全局变量

时间:2017-10-03 05:33:57

标签: python variables global setdefault

我对使用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!

4 个答案:

答案 0 :(得分:2)

my_list被定义为fill_func内的局部变量;这是在全局范围内定义的另一个my_list。

因此,您的代码首先调用打印本地fill_func的{​​{1}},然后调用默认的dict。然后它退出函数并打印外部范围my_list和字典(未被遮蔽)

答案 1 :(得分:1)

您正在创建一个与全局变量同名的局部变量。只需在函数顶部添加global my_list即可。

答案 2 :(得分:1)

这是因为,正如你正确指出的那样,它与范围有关。 my_listmy_dicttest.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

请注意,通常最好只使用大写字母来表示全局,以避免混淆