2

似乎脚本中定义的类与导入脚本的类具有不同的范围。例如:

在文件 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() 的类都必须驻留在主文件中。如何确保导入的类具有相同的全局范围?在阅读此处此处的其他帖子后,我尝试过的一些事情包括:

module = __import__("foo", fromlist="foo")
globals()["foo"] = getattr(module, "foo")

__builtin__.foo = foo

任何帮助表示赞赏!

[编辑] - -

因此,根据上面的链接,这是在重复的文章中回答的。事实证明,范围不是跨模块共享的。它提到了几种解决方法,但在我的情况下,我需要实际创建/读取/写入全局变量。所以我在主脚本中创建了一个例程,并在初始化 foo 和 bar 时将其作为对象传递。例如:

def PrintGlobals():
    print globals()

class bar(object):
    def __init__(self, PrintGlobals):
        self.PrintGlobals = PrintGlobals
        self.PrintGlobals()

classinternal = bar(PrintGlobals)

(不是我选择这一切应该如何工作,在我有时间与应用程序开发人员相处之前,这是一种黑客行为:-)

4

1 回答 1

2

以下是 Python 3常见问题解答的内容:

在 Python 中,仅在函数内部引用的变量是隐式全局的。如果一个变量在函数体内的任何地方都被赋值,除非明确声明为全局变量,否则它被假定为局部变量。

虽然起初有点令人惊讶,但片刻的考虑解释了这一点。一方面,对已分配的变量要求全局性提供了防止意外副作用的障碍。另一方面,如果所有全局引用都需要全局,那么您将一直使用全局。您必须将对内置函数或导入模块组件的每个引用声明为全局。这种混乱会破坏全局声明识别副作用的有用性。

要查看不同范围内的全局变量,请尝试在执行期间的不同点执行 print(globals())。例如:在运行任何代码之前的顶级模块,然后__init__.py如果你有任何代码在那里(因为你导入 foo),在 foo 的模块级别,在每个函数中,以及在你修改传递给的任何变量之前/之后功能。

这个答案进一步解释了:

我认为您在这里缺少的关键是每个模块都有自己的“全局”命名空间。一开始这可能有点令人困惑,因为在像 C 这样的语言中,所有外部变量和函数共享一个全局命名空间。但是一旦你超越了这个假设,Python 的方式就很有意义了。

但是请注意,__init__.py当您导入包或包中的模块时,包文件中分配的所有名称都可以在包命名空间中使用。

于 2015-11-18T21:55:06.450 回答