【问题标题】:Very basic Python project structure fails非常基本的 Python 项目结构失败
【发布时间】:2022-01-04 22:44:01
【问题描述】:

我有以下项目:

apack/
  apack/
    __init__.py
    apack.py
    aux.py
  setup.py

apack.py:

def foo(x):
    return x

aux.py:

from apack import foo

def bar():
    return foo() + 1

setup.py:

from setuptools import setup, find_packages

setup(
    name='apack',
    packages=find_packages()
)

我使用pip install . 安装软件包。但是,结果是一个空包:

>>> import apack
>>> apack.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'apack' has no attribute 'foo'

我想要的是:

>>> import apack
>>> apack.foo()
>>> apack.bar()

这里有许多类似的问题(例如,12)。但是,它们都不足以让我理解为什么我的示例不起作用。

【问题讨论】:

    标签: python setuptools setup.py


    【解决方案1】:

    当您导入包时,它会调用包的__init__ 文件。您可以在 python 解释器中确认这一点。

    >>> import json
    >>> json.__file__
    '<PATH>\\lib\\json\\__init__.py'
    

    因此,要从您的包级别获得foobar,您必须将foobar 导入到您的包的__init__ 文件中。即,

    from .apack import foo
    from .aux import bar
    

    【讨论】:

    • 添加:然后在aux.py 中而不是from apack import foo,相对导入:from .apack import foo
    • @Felipe 为什么?我目前拥有的似乎有效。
    • @Felipe 摘自 PEP stackoverflow.com/a/12738912/1398282。但是,解释中涉及到“包内的模块不能轻易地导入自身”等一系列模糊性。为什么模块会自己导入?一个模块总是可以访问它自己的命名空间,我通过将一个模块导入到自己来得到什么?
    • 关于相对导入 - 老实说,在您提出问题之前(以及此后我的后续研究),我一直认为这是推荐的。似乎PEP8 实际上建议相反——绝对而不是相对进口。关于最后一条评论,我相信它们的意思是相对导入允许您导入模块本身。换句话说,在aux.py 中你可以做from . import aux。我看到有人想要这样做的唯一原因是为模块命名空间内的每个 func/objs/declarable 指定模块。
    • 想象aux.py 导入foo.bar() 并在其中包含bar() 函数。在aux.py 中执行from . import aux 将允许您将bar() 函数用作foo.bar()aux.bar(),区分两者。再说一次 - 我对为什么这会有用的唯一想法。我自己从未在野外遇到过这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2021-02-01
    • 2012-01-31
    相关资源
    最近更新 更多