如何在 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 脚本中为导入的类获得相同的范围? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Python 导入其他文件中的类

如何在我的精灵套件游戏 Swift 中为所有 iPhone 获得相同的布局尺寸

如何导入和使用在另一个python程序的类中定义的变量?

无法在 python 中为 ubuntu 16.04 上的 libreoffice 导入 uno

如何在 Python 中为注册页面创建测试脚本?

如何在 docker (Azure Web App) 中为 Python 导入 cv2?