跨模块的 Python 作用域/命名空间

标签 python scope

我有一个与 python 范围界定相关的问题。下面是代码片段:

文件:settings.py

#module settings
fruit = 'banana'

def set_fruit(val):
    global fruit
    print 'Setting fruit ', fruit, ' to ', val
    fruit = val

文件:helper.py

#module helper
from settings import fruit

class Helper(object):
    def __init__(self):
        print 'Inside Helper fruit = ', fruit

文件:controller.py

#module controller
import settings
import helper

class Controller(object):
    def __init__(self):
        settings.set_fruit('apple')
        print 'Controller: settings.fruit = ', settings.fruit

Controller()
print 'fruit = ', settings.fruit
helper.Helper()

settings.py 具有供各种模块使用的全局设置。其中一些设置需要在 Controller 启动期间进行更改。我想知道为什么 Controller 更改的设置对其他人不可见,在本例中对帮助程序模块不可见。

这是我得到的输出:

$ python controller.py
Setting fruit  banana  to  apple
Controller: settings.fruit =  apple
fruit =  apple
Inside Helper fruit =  banana

最佳答案

当您执行from settings importfruit时,您在helper模块中创建了一个新的fruit名称,该名称​​是独立的 来自 settings.fruit 名称。它仅仅引用同一个对象。

然后,您的 settings.set_fruit() 方法会重新绑定(bind) settings.fruit 以将其指向一个新对象,但 helper.fruit引用不能跟风;毕竟它是分开的。

所有这一切与创建两个引用一个值的单独局部变量没有什么不同:

fruit = 'banana'
another_fruit = fruit
fruit = 'apple'
print another_fruit

解决方法是执行您在 controller 模块中所做的操作;仅将 settings 中的名称引用为模块上的属性。这样,您将始终只使用一个引用,即对在其他模块之间共享的 settings 模块的引用。

关于跨模块的 Python 作用域/命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27004736/

相关文章:

python - cvxpy STLibc++ 在 MacOS Mojave 上安装错误

javascript - 如何将 Proxy 对象作为上下文传递给 JavaScript 中的闭包

jquery - 传递 ID 属性

javascript - 对 'this' 的内部引用未在返回对象中解析

c++ - 在源文件中定义但在任何函数定义之外的变量的范围是什么?

python - dask:指定进程数

python - 合并具有许多稀疏列的两个 Pandas DataFrame 会导致 DataFrame 需要不成比例的大量内存

Python arrow包时区错误?

python - 通过网络发送python ctypes结构

c - 范围和链接有什么区别?