简体   繁体   English

为什么全局变量不能像导入时那样工作?

[英]Why doesn't globals work as I would expect when importing?

In the file foo.py I have this: foo.py文件中我有这个:

d = {}
d['x'] = 0
x = 0

def foo():
    global d
    global x
    d['x'] = 1
    x = 1

Then in an interpreter: 然后在翻译中:

>>> from foo import *
>>> d['x']
0
>>> x
0
>>> foo()
>>> d['x']
1
>>> x
0

I expected this: 我期待这个:

>>> x
1

What am I not understanding? 我不明白的是什么?

The global namespace of foo is imported into your current namespace only once (when you do the from foo import * ). foo的全局命名空间只导入到当前命名空间一次(当你执行from foo import * )。 After that, if you change foo 's namespace, it won't be reflected in your current namespace. 之后,如果更改foo的命名空间,它将不会反映在当前的命名空间中。

Note that you can still change objects in foo 's namespace and see the changed in your current namespace. 请注意,您仍然可以更改foo命名空间中的对象,并查看当前命名空间中的更改。 That is why you see changes in d . 这就是为什么你看到d变化。 You still have a reference to the same object d that lives in foo 's namespace. 您仍然可以引用foo命名空间中的同一个对象d

But, when you set: 但是,当你设置:

x = 1

This rebinds a new object in the namespace of foo . 这将重新绑定 foo命名空间中的新对象。

Your foo module and the main module that imports it (named __main__ ) have separate namespaces. 您的foo模块和导入它的主模块(名为__main__ )具有单独的命名空间。

Here's what happens: 这是发生的事情:

  1. Importing foo sets foo 's global variable x to refer to the integer object 0 . 导入foo设置foo的全局变量x以引用整数对象0
  2. This reference is copied into __main__ as the global variable x . 此引用将作为全局变量x复制到__main__中。
  3. You call foo.foo() , which sets foo 's global variable x to refer to the integer object 1 . 你调用foo.foo() ,它设置foo的全局变量x来引用整数对象1
  4. You print __main__ 's global variable x . 你打印__main__的全局变量x Because you never changed what this x refers to, it still refers to 0 , which is what is printed. 因为你从未改变过这个x引用的内容,所以它仍然引用0 ,即打印的内容。

In short, importing a name into a module does not create any kind of binding between the names in the two modules. 简而言之,将名称导入模块不会在两个模块中的名称之间创建任何类型的绑定。 They initially refer to the same value, but if one name is re-bound to a different object, the other does not necessarily follow. 它们最初引用相同的值,但如果一个名称重新绑定到另一个对象,则另一个名称不一定遵循。

This is (one) reason why import foo is generally a better idea. 这是(一) import foo通常是一个更好的主意的原因。 Referring to foo.x explicitly in __main__ refers exactly to foo 's global variable x , and will refer to the name's current value even if it has been changed. __main__明确地引用foo.x指的是foo的全局变量x ,并且即使它已被更改,也将引用该名称的当前值。

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

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