如何在 Python 脚本中为导入的类获得相同的范围? [复制]
Posted
技术标签:
【中文标题】如何在 Python 脚本中为导入的类获得相同的范围? [复制]【英文标题】:How to get the same scope for imported classes in a Python script? [duplicate] 【发布时间】:2016-02-20 19:31:22 【问题描述】:似乎在脚本中定义的类与导入到脚本中的类具有不同的范围。例如:
在文件 foo.py 中:
class foo(object):
def __init__(self):
print globals()
在我的主文件中:
from foo import foo
class bar(object):
def __init__(self):
print globals()
classimport = foo()
classinternal = bar()
从 foo 和 bar 返回的全局变量列表不同 - 这是为什么呢?
这让生活变得很困难,因为任何需要访问主 globals() 的类都必须驻留在主文件中。如何确保导入的类具有相同的全局范围?我在阅读其他帖子here 和here 后尝试过的一些事情包括:
module = __import__("foo", fromlist="foo")
globals()["foo"] = getattr(module, "foo")
和
__builtin__.foo = foo
任何帮助表示赞赏!
[编辑] ---
因此,根据上面的链接,这是在 duplicate article 中回答的。事实证明,范围不是跨模块共享的。它提到了几种解决方法,但在我的情况下,我需要实际创建/读取/写入全局变量。所以我在主脚本中创建了一个例程,并在初始化 foo 和 bar 时将其作为对象传递。例如:
def PrintGlobals():
print globals()
class bar(object):
def __init__(self, PrintGlobals):
self.PrintGlobals = PrintGlobals
self.PrintGlobals()
classinternal = bar(PrintGlobals)
(不是我选择这一切应该如何工作,在我有时间与应用程序开发人员相处之前,这是一种黑客行为:-)
【问题讨论】:
与其使用全局变量,不如将所需信息传递给数据类型中的函数或方法。例如,如果您使用字典,那么与 **kwargs 配合得非常好。或者,如果需要,可以考虑使用 PyYAML 之类的包来读取配置文件。您要解决什么具体问题? 全局变量属于定义函数的模块。 This post 可能会给你一个关于这个问题的很好的概述。 【参考方案1】:以下是 Python 3 FAQ 所说的:
在 Python 中,仅在函数内部引用的变量是隐式全局的。如果一个变量在函数体的任何地方都被赋值,除非明确声明为全局变量,否则它会被假定为局部变量。
虽然一开始有点令人惊讶,但稍加思考就可以解释这一点。一方面,对已分配的变量要求全局性提供了防止意外副作用的障碍。另一方面,如果所有全局引用都需要全局,那么您将一直使用全局。您必须将每个对内置函数或导入模块组件的引用声明为全局。这种混乱会破坏全局声明识别副作用的有用性。
要查看不同范围内的全局变量,请尝试在执行期间的不同时间点执行 print(globals())。例如:在运行任何代码之前的***模块,然后在__init__.py
中,如果您有任何代码(因为您导入 foo),在 foo 的模块级别,在每个函数中,以及在您修改任何代码之前/之后传递给函数的变量。
This answer进一步解释:
我认为您在这里缺少的关键是每个模块都有自己的“全局”命名空间。一开始这可能有点令人困惑,因为在像 C 这样的语言中,所有外部变量和函数共享一个全局命名空间。但是一旦你超越了这个假设,Python 的方式就很有意义了。
但是请注意,当您导入包或包中的模块时,包__init__.py
文件中分配的所有名称都可以在包命名空间中使用。
【讨论】:
以上是关于如何在 Python 脚本中为导入的类获得相同的范围? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在我的精灵套件游戏 Swift 中为所有 iPhone 获得相同的布局尺寸