Python模块之间的导入和全局变量

6
我有一个问题,似乎非常基础,但我似乎无法在任何地方找到帮助。
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。)
4个回答

5
我的理解有误吗?
是的,因为行 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中定义变量__all__,它列出了应该被星号操作符导入的内容。
希望对您有所帮助!

4
当你导入一个模块时,该模块中定义的所有变量都在其命名空间中可用。因此,如果file_a模块中有XYZ,当你执行import file_a时,你可以将XYZ作为file_a.XYZ访问。
这里的一般思想是,你的命名空间不应该被其他命名空间的内容所混淆。

3

是的,你的理解是错误的。每个模块都有自己的命名空间,在该文件中只有在显式导入的内容才能在该命名空间中使用。

与其他答案不同,虽然这样做是可行的,但使用file_a.XYZ不是特别符合Pythonic。相反,你应该在file_b的顶部导入XYZ和sys。


那就是我的问题。我想避免在像file_b这样的许多文件中重复一组导入。我知道将XYZ和sys导入到file_b中可以解决这个问题。 - ksrini
1
@ksrini 你不应该这样想。显式地导入模块所需的所有内容是很好的做法。它能够把所有依赖关系整齐地列在一个地方。详见PEP20 - 明确胜于隐含。 - yak
谢谢你,Yak。那很有趣,也很有见地! - ksrini

1
import file_a
from file_a import A

我认为问题在于:你没有真正导入XYZ!

from fila_a import * 

可以解决你的问题,但这不是一个好的方式~~~

你可以把这个写进文件_b:

from file_a import XYZ

完成了吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接