Python 跨模块导入和全局变量

6 投票
4 回答
9035 浏览
提问于 2025-04-17 06:29

我有一个问题,看起来很基础,但我在任何地方都找不到帮助。

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。即使是像 'import sys' 这样的标准导入,从 file_a 中做的,也似乎在 file_b 中无法使用。我原以为这样是可以的。我的理解错了吗?如果是的话,有没有办法在不同的文件之间共享导入的内容和全局变量?(如果这有帮助的话,我之前是 C++ 和 Java 的程序员,现在开始学习 Python。)

4 个回答

3

是的,你的理解有点偏差。每个模块都有自己的命名空间,只有你在那个文件里明确导入的东西才能在这个命名空间中使用。

和其他回答不同,直接用 file_a.XYZ 这种方式并不是特别符合Python的风格,虽然这样是可以工作的。更好的做法是在 file_b 的开头导入 XYZ 和 sys。

4

当你导入一个模块时,那个模块里定义的所有变量都可以在它的命名空间中使用。也就是说,如果在file_a模块里有一个叫XYZ的东西,当你使用import file_a时,你可以通过file_a.XYZ来访问这个XYZ

这里的主要意思是,你的命名空间不应该被其他命名空间的内容搞得乱七八糟。

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_a 中所有的导入也带到 file_b 中。你最终会失去对导入的控制,这在某个时候会给你带来麻烦……相信我!

当出于某种原因需要使用 from module import * 时,可以在 module 中定义一个 变量 __all__,这样可以指定哪些内容可以通过星号操作符导入。

希望这对你有帮助!

撰写回答