【问题标题】:Python - How do I import parent package from extended namespacePython - 如何从扩展命名空间导入父包
【发布时间】:2014-01-21 14:40:46
【问题描述】:

所以我有两个不同的包。第一个是我的主包“bobzilla”,另一个包扩展了第一个“bobzilla.structure”。

bobzilla/
  __init__.py

bobzilla/__init__.py 包含的位置:

class Foo(object):
    def __init__(self, bar):
        self.bar=bar

还有:

bobzilla/
  __init__.py
  structure/
    __init__.py

bobzilla/structure/__init__.py 包含的位置:

import bobzilla
foo=Foo("bar")

执行 bobzilla/structure/__init__.py 时,我得到:

AttributeError: 'module' object has no attribute 'Foo'

我的问题是,如何在不覆盖“bobzilla.structure”的情况下从“bobzilla.structure”引用命名空间“bobzilla”。

注意:

设置“这个问题在这里可能已经有答案”的人是错误的。我已经尝试过了,但它没有用。这是两个不同的包,不是同一个。

【问题讨论】:

  • 你不能。命名空间包必须为空。
  • @MartijnPieters 好的,所以我只需从 bobzilla.structure-package 中删除 bobzilla/__init__.py 然后使其成为命名空间包,它应该可以工作吗?
  • 您使用的是哪个版本的 Python?您是在尝试创建经典的显式命名空间包,还是 PEP420 风格的隐式包?如果是前者,您能告诉我们您的相关extend_pathdeclare_namespace 代码吗?如果是后者……您使用的是 Python 3.3 或更高版本,对吗?

标签: python namespaces packages extend


【解决方案1】:

bobzilla/structure/__init__.py 应该是:

from bobzilla import Foo
foo=Foo("bar")

使用问题中提到的相同结构和代码测试上述内容。 bobzilla/path/to/test。结果:

>>> from site import addsitedir
>>> addsitedir("/path/to/test")
>>> import bobzilla.structure as struc
>>> struc.foo
<bobzilla.Foo object at 0x7f2f8c716810>
>>> 

【讨论】:

  • 'from .. import bobzilla' 不起作用。只得到 'ImportError: cannot import name bobzilla'。
  • 问题是 Foo 类在 bobzilla/__init__.py 中,它不是 bobzilla/foo.py(如果这有意义的话)。所以你建议的只是错误的'ImportError: cannot import name Foo'。
  • @endlessretry 将上述测试结果添加到答案中。鉴于问题中的描述,该错误不可重现。
【解决方案2】:

试试:

import bozilla.structure as struct
import bozilla

NLTKhttp://nltk.org 的工作示例:

>>> import nltk.corpus as corpus
>>> nltk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'nltk' is not defined
>>> import nltk
>>> nltk.corpus
<LazyModule 'nltk.corpus'>
>>> corpus
<LazyModule 'nltk.corpus'>

【讨论】:

    【解决方案3】:

    看起来您正在尝试创建一个命名空间包而不创建一个命名空间包,这……是行不通的。

    要明确地将包指定为命名空间包,您需要使用pkgutil 库(或setuptools 中更高级的东西),类似于bobzilla/__init__.py 顶部的内容:

    __path__ = pkgutil.extend_path(__path__, __name__)
    

    如果您想要implicit namespace package,您可以在 Python 3.3 及更高版本中执行此操作……但前提是 bobzilla。隐式命名空间包不能包含__init__.py 文件,并且除了它们的模块之外永远不会有任何内容。 (好吧,你可以创建一个隐式命名空间包,然后添加一个子包或外部模块,在创建后显式地向其中添加内容……但我不确定你为什么要这样做。)

    【讨论】:

      猜你喜欢
      • 2017-05-10
      • 2017-11-24
      • 2012-01-08
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      相关资源
      最近更新 更多