简体   繁体   English

python中带有setdefault的全局变量

[英]global variable with setdefault in python

I'm a bit confused about the behavior of global variables with the use if setdefault() in python: 我对全局变量的行为和python中的if setdefault()的使用感到有些困惑:

Please find sample code for how this are referenced/resolved using setdefault, can somebody help me clarify what is going on in here? 请找到示例代码以了解如何使用setdefault引用/解决此问题,有人可以帮我弄清楚这里发生了什么吗?

Main file where variables are resoved : 解析变量的主文件:

#main
from test import *

fill_func()

print my_list
print my_dict

Test file where variables are assigned values : 测试文件中为变量分配了值:

#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

Output : 输出:

[1, 2, 3]
{0: ['zero']}
[]
{0: ['zero']}

I'm not able to understand why the list(my_list) variable shows empty when called from main.py, whereas my_dict shows data fine? 我无法理解为什么从main.py调用list(my_list)变量时显示为空,而my_dict显示数据正常吗?

Any help is appreciated. 任何帮助表示赞赏。 TIA! TIA!

#

Sample test file 2 样本测试文件2

{0: ['zero']}
[1, 2, 3]
[]
{0: ['zero']}

Ouput :

 {0: ['zero']} [1, 2, 3] [] {0: ['zero']} 

Can someone please throw some light on the second test file, please bear with me, trying to understand the basics :) 有人可以在第二个测试文件上介绍一下吗,请忍受我,尝试了解基本知识:)

TIA! TIA!

my_list is defined as a local variable inside the fill_func ; my_list定义为fill_func内部的局部变量; this is shadowing the other my_list defined in the global scope. 这掩盖了在全局范围内定义的另一个my_list。

therefore, your code first calls the fill_func that prints the local my_list , then the default dict. 因此,您的代码首先调用fill_func ,该fill_func将打印本地my_list ,然后显示默认dict。 It then exits the function and prints the outer scope my_list , and the dict (which was not shadowed) 然后退出函数并打印外部作用域my_list和dict(未阴影)

You are creating a local variable with the same name as the global variable. 您正在创建一个与全局变量同名的局部变量。 Just add global my_list at the top of the function. 只需在函数顶部添加global my_list

That's because, as you've rightly indicated, it has to do with scope. 这是因为,正如您正确指出的那样,它与范围有关。 my_list and my_dict are global to test.py , which have to accessed using the global qualifier. my_listmy_dicttest.py是全局的,必须使用global限定符对其进行访问。 That is, your code should be: 也就是说,您的代码应为:

# 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

EDIT: 编辑:

To get the both the list and the dictionary to update, one has to extend the list, and modify the dictionary (as you've done) - ie actually change its value. 为了同时获取列表和字典,必须扩展列表并修改字典(如您所完成的)-即实际上更改其值。 Assigning it a value using the assignment operator only changes what the variable refers to and not the value itself. 使用赋值运算符为它赋值只会更改变量所指的内容,而不会更改值本身。 This is why it doesn't update outside of the local function scope. 这就是为什么它不会在本地函数范围之外更新的原因。 And, this is also why it updates when we use other methods to modify the contents of those variables. 并且,这也是为什么当我们使用其他方法修改那些变量的内容时它会更新的原因。

The problem is when a function body is parsed all the variables used in either normal assignments or augmented assigments are considered as local variables, so when the function gets called Python will not look for those variables in global scope hence it will raise an error. 问题在于,当解析函数主体时,所有在常规分配或扩充分配中使用的变量都被视为局部变量,因此在调用函数时,Python将不会在全局范围内查找这些变量,因此会引发错误。 Hence you need to specify those variables as global to tell Python to look for them in global scope. 因此,您需要将这些变量指定为全局变量,以告诉Python在全局范围内查找它们。

Another alternative is to use list.extend() 另一种选择是使用list.extend()

(From here: https://stackoverflow.com/a/23436510/866930 . An additional reference that's useful on this is: https://stackoverflow.com/a/31437415/866930 ) (从此处: https : //stackoverflow.com/a/23436510/866930 。对此有用的其他参考是: https : //stackoverflow.com/a/31437415/866930

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. 仅在要更改变量名称引用的对象时才需要全局语句。

Compare to this version: 与此版本比较:

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

Without the use of global , Python would think that the variable is local to the scope of the code element where it was defined, hence global tells the interpreter to look within the globals symbol table (these contents can be accessed via globals() ) 如果不使用global ,Python会认为该变量在定义它的代码元素的作用域内是局部的,因此global告诉解释器在globals符号表中查找(这些内容可以通过globals()访问)

you need to declare in your function that you want to use the global variable. 您需要在函数中声明要使用全局变量。

You can do that by 你可以这样做

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

Please note that normally it is preferred to use only CAPITAL LETTERS for globals to avoid confusion 请注意,通常最好只对大写字母使用大写字母以避免混淆

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM