【问题标题】:Reference objects in containing package?包含包中的引用对象?
【发布时间】:2011-02-03 05:54:26
【问题描述】:

我有一个包spam,其中包含一个变量_eggs in __init__.py 在同一个包中,在boiler.py 中,我有类Boiler

Boiler,我想在包的__init__.py文件中引用_eggs。有没有办法可以做到这一点?

【问题讨论】:

    标签: python namespaces python-3.x


    【解决方案1】:

    检索该值的最合适方法是通过显式相对导入:

    from . import _eggs
    

    但是,要记住的一件事是,以下命令行调用将无法工作:

    python spam/boiler.py
    

    这不起作用的原因是解释器无法将任何直接执行的文件识别为包的一部分,因此相对导入将失败。

    但是,将您当前的工作目录设置为包含“垃圾邮件”文件夹的目录,您可以改为执行该模块:

    python -m spam.boiler
    

    这为解释器提供了足够的信息来识别boiler.py 在模块层次结构中的位置并正确解析相关导入。

    这仅适用于 Python 2.6 或更高版本 - 以前的版本根本无法处理来自 ma​​in 的显式相对导入。 (有关血腥细节,请参阅PEP 366)。

    如果您只是从另一个文件执行 import spam.boiler,那么这应该适用于任何允许显式相对导入的 Python 版本(尽管 Python 2.5 可能需要 from __future__ import absolute_imports 才能正确启用此功能)

    【讨论】:

    • "from .import _eggs" 给了我一个 ImportError ("cannot import name _eggs") 和 "from spam import _eggs"。我不知道这里的规则是否针对 Python 3 发生了变化,但这两种解决方案都不起作用。
    • 我发现这样做的唯一方法就是根本不这样做;而是将这些东西放在一个名为 _common.py 或其他东西的模块中,然后执行“from ._common import _eggs”。为什么我似乎无法用__init__.py 中的_eggs 做到这一点,这超出了我的理解。
    • 等等,你是如何执行boiler.py的?通过另一个模块中的“import spam.boiler”?通过“python -m spam.boiler”?通过“python spam/boiler.py”?还是通过“python锅炉.py”?前两种方法中的任何一种都应该有效,但后两种会出现问题(出于很好的原因,直接执行位于包内的模块被认为是不可取的)
    • 我做了一些实验,它确实对我有用。不过那是 2.7 - 哪个版本让您感到悲伤?
    • 我使用的是 Python 2.6(仍然是);无论如何,我最终只是在包中使用了一个模块,因为我有其他相关代码,而且这种组织是有意义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多