【问题标题】:Dynamically merging file modules with directory modules in Python在 Python 中动态合并文件模块和目录模块
【发布时间】:2016-04-03 08:09:23
【问题描述】:

给定一个具有以下结构的目录:

├── foo
│   ├── bar
│   │   └── baz.py
│   └── bar.py
└── foo.py

以及以下文件内容:

foo.py

class Foo:
    pass

foo/bar.py

class Bar:
    pass

foo/bar/baz.py

class Baz:
    pass

我希望能够从其他文件中完成所有这些事情:

from foo import Foo
from foo.bar import Bar
from foo.bar.baz import Baz

即好像每个文件中的定义都与组成同名目录的模块定义“合并”了。如何以不需要我手动指定每条路径的动态方式(无论是否涉及__init__.py)来完成此任务?

当我在每个目录中放置空的__init__.py 文件并尝试执行上述导入时,我收到以下错误:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    from foo import Foo
ImportError: cannot import name 'Foo'

在我看来,这表明foo.py 文件已被foo 目录覆盖,因此foo.py 中的定义不可见。

【问题讨论】:

  • 您的意思是希望您避免输入foo.bar.baz?在这种情况下,是的,使用__init__.py 文件相当容易。
  • 不,我可以完全按照所示输入导入。我已经用我尝试这样做时遇到的错误更新了问题。
  • 当我说“以一种不需要我手动指定每个路径的动态方式”时,我的意思是我不想更新 __init__.py 文件,因为例如,包含我想要此行为的每个新文件/目录。

标签: python module package


【解决方案1】:

尝试做:

import foo
print(foo.__file__)

使用您显示的文件夹结构,我希望结果类似于:

.../foo.py

但是,当您将 __init__.py 添加到 foo 文件夹时,它将改为:

.../foo/__init__.py

使用 python 包,您实际上无法导入文件夹,因此最终发生的情况是您从该文件夹而不是 foo.py 导入 __init__.py 文件,因此您需要做的就是将 foo.py 移动到文件夹中并将其重命名__init__.py,然后您可以像现在设置它一样使用import foofrom foo import Foo

【讨论】:

  • 谢谢——这很有意义,而且听起来比手动合并两组单独的定义要好得多。
  • 我真的希望the documentation 描述了__init__.py 的实际用途,而不仅仅是“init.py 可以只是一个空文件,但它也可以执行初始化包的代码或设置 _all_ 变量”_init_.py 文件包含包级变量
猜你喜欢
  • 1970-01-01
  • 2020-03-02
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多