跨模块和全局变量的 Python 导入
Posted
技术标签:
【中文标题】跨模块和全局变量的 Python 导入【英文标题】:Python imports across modules and global variables 【发布时间】:2011-12-31 05:31:33 【问题描述】:我有一个似乎相当基本的问题,但我似乎无法在任何地方找到任何帮助。
file_a.py >>
from xyz import XYZ
class A:
.
.
.
file_b.py >>
import file_a
from file_a import A
class B(A):
def __init__(self):
A.__init__(self)
def someMethod(self):
XYZ.doSomething()
XYZ.doSomething() 失败,提示 NameError: name 'XYZ' is not defined 即使从 file_a 完成的标准导入(如“import sys”)似乎也无法使其在 file_b 中可用。我认为应该可以。我的理解错了吗?如果是,那么有没有办法在文件之间有通用的导入和全局变量? (如果有帮助的话,我曾经是一名 C++ 和 java 程序员,现在开始使用 python。)
【问题讨论】:
【参考方案1】:我的理解有误吗?
是的,因为from file_a import A
行仅将类A
导入file_b
的命名空间。 file_a
的命名空间保持不变。如果不是这样,那么同时使用这两种语法就没有什么意义了:
import modulename
from modulename import something
如果你的想法是对的,那么在第二种形式之后你总是可以使用modulename.someotherthing
。
如果是,那么有没有办法在文件中使用通用导入和全局变量?
是的,带有星号*
运算符:
from modulename import *
但这带来了命名空间污染的问题,例如from file_a import *
将导入file_b
以及所有在file_a
中完成的导入。你将最终失去对你的进口的控制,这会在某个时候咬你...相信我!
当出于某种原因需要from module import *
时,命名空间污染的解决方法是在module
中定义variable __all__
,它将应使用星号运算符导入的内容列入白名单。
HTH!
【讨论】:
【参考方案2】:当您导入一个模块时,该模块中定义的所有变量都在其命名空间中可用。因此,如果XYZ
在file_a
模块中可用,则当您import file_a
时,您可以将XYZ
作为file_a.XYZ
访问。
这里的总体思路是,您的命名空间不应与其他命名空间的内容混杂在一起。
【讨论】:
【参考方案3】:是的,你的理解是错误的。每个模块都有自己的命名空间,只有您在该文件中显式导入的内容才能在该命名空间中使用。
与其他答案相反,引用file_a.XYZ
并不是特别Pythonic,尽管这会起作用。相反,您应该在 file_b
的顶部导入 XYZ 和 sys。
【讨论】:
那是我的问题。我想避免在 file_b 等许多文件中重复一组导入。我知道将 XYZ 和 sys 导入 file_b 是可行的。 @ksrini 你不应该这样。显式导入模块使用的所有内容是很好的。它将所有依赖项整齐地列出在一个地方。请参阅 PEP20 - 显式优于隐式。 谢谢yak,这很有趣,很有见地!【参考方案4】:import file_a
from file_a import A
我认为问题在于:你并没有真正导入 XYZ!
from fila_a import *
可以解决你的问题,但不是好办法~~~
你可以在 file_b 中写这个:
from file_a import XYZ
完成了吗?
【讨论】:
以上是关于跨模块和全局变量的 Python 导入的主要内容,如果未能解决你的问题,请参考以下文章