gpt4 book ai didi

python - 为什么模块全局分配与类/字典不同的简单类型?

转载 作者:太空宇宙 更新时间:2023-11-03 11:29:02 25 4
gpt4 key购买 nike

给定以下示例代码:

测试.py

import module

print 'main: Vars.foo: %s' % (module.Vars.foo)
print 'main: d.foo: %s' % (module.d['foo'])
print 'main: foo: %s' % (module.foo)
print
module.Vars.foo = 2
module.d['foo']=2
module.foo = 2

def baz():
print 'baz: Vars.foo: %s' % (module.Vars.foo)
print 'baz: d.foo: %s' % (module.d['foo'])
print 'baz: foo: %s' % (module.foo)
print
module.bar()

if __name__ == '__main__':
baz()

模块/
模块.py
__init__.py

__init__.py

from module import *

模块.py

class Vars:
foo = None
d = {'foo': None}
foo = None

def bar():
print 'bar: Vars.foo: %s' % (Vars.foo)
print 'bar: d.foo: %s' % (d['foo'])
print 'bar: foo: %s' % (foo)

在运行 test.py 时产生这个输出:

main: Vars.foo: None
main: d.foo: None
main: foo: None

baz: Vars.foo: 2
baz: d.foo: 2
baz: foo: 2

bar: Vars.foo: 2
bar: d.foo: 2
bar: foo: None

除 bar() 输出外,所有这些对我来说都有意义。为什么类/字典与简单类型的 bar() 输出不同?我认为这与类/字典的可变性有关,但我不确定。我特别要寻找的是导致该栏输出保持原样的实际 python 语言规则。

最佳答案

不同之处在于你正在变异 Varsd , 但您只是为 foo 分配了一个新值.

您将包和模块都命名为“模块”,这让您的示例有些困惑。这是误导性的,因为尽管您的两个导入似乎都是从 module 导入的,它们不会从同一个文件导入。我将像这样重命名你的东西以进行解释:

package/
module.py
__init__.py

test.py 中的导入然后变成import package (因为test.py在包外,所以它唯一能直接导入的就是包)。但是导入__init__.py还是from module import * (因为它是从同一包中的另一个模块导入的)。

test.pyimport package ,那么它导入的是__init__.py包的。里面有一些东西 __init__.py因为__init__.py做了from module import * .然而,from module import *创建一个新的命名空间,其中包含 module.py 中的所有内容.无论您如何访问它们,改变对象都会产生影响,但为名称分配新值只会影响那个命名空间。

然后,当你做 package.Vars.foo = 2 ,你改变了类对象。当你做 package.d['foo'] = 2 ,你改变了 dict 对象。但是当你做 package.foo = 2 ,您只是为值 foo 分配了一个新名称在 __init__.py . (或者,从另一个角度来看,您正在改变 __init__.py 的模块对象。)这留下了原始变量 foo。在 module.py不受影响。

函数bar看到 Vars 的突变和 d , 但它正在访问变量 d在它自己的命名空间中,而不是 __init__.py 的命名空间,因此它看不到分配给 package.foo 的任何新值.

简而言之,您看到的行为与此基本相同:

x = {'foo': None}
y = None

a = x
b = y

a['foo'] = 2
b = 2

在此之后 x将是 {'foo': 2} ,但是y仍然是无。为什么?因为a['foo'] = 2改变 a 引用的对象;自 x指的是同一个对象,它“看到”了突变。但是b = 2只是为 b 分配了一个新名称.这与您的示例中发生的情况相同;只是稍微有点难看,因为突变和赋值发生在不同的命名空间中。

关于python - 为什么模块全局分配与类/字典不同的简单类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27301700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com