【问题标题】:Python imports across modules and global variables跨模块和全局变量的 Python 导入
【发布时间】:2014-02-18 10:57:59
【问题描述】:

我有一个似乎相当基本的问题,但我似乎无法在任何地方找到任何帮助。

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。)

【问题讨论】:

    标签: python import python-module


    【解决方案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】:

      当您导入一个模块时,该模块中定义的所有变量都在其命名空间中可用。因此,如果XYZfile_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
        

        完成了吗?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-06-02
          • 2016-10-20
          • 1970-01-01
          • 1970-01-01
          • 2018-11-21
          • 2017-04-30
          相关资源
          最近更新 更多