Python:如何导入没有 python-filename 作为子模块的模块?

Lae*_*nan 5 python module python-import python-3.x

描述

假设,我有一个具有以下结构的包:

package-folder
  |_ mypackage
     |_ __init__.py
     |_ module1.py
  setup.py
Run Code Online (Sandbox Code Playgroud)

哪里__init__.py是空的

module1.py

def do_stuff():
    print('Did stuff.')
Run Code Online (Sandbox Code Playgroud)

setup.py包含用于制作软件包的常用上下文,可以安装pip install -e pkgpath在本地系统上。

在 a 中script.py,我必须这样做:

import mypackage as abbr

abbr.module1.do_stuff()
# output: Did stuff.
Run Code Online (Sandbox Code Playgroud)

我想要的电话是:

abbr.do_stuff()
# output: Did stuff.
Run Code Online (Sandbox Code Playgroud)

问题

  1. 我如何“组织”我的包,以便我可以直接从 module1.py 调用函数abbr.function()?需要修改哪些代码?
  2. 如果包增长,这个组织是否有用?那么目录将充当结构元素,而 python 文件只是用于组织我的功能的胶囊?
  3. 在模块和子模块中组织功能的最佳方法是什么?

进一步的想法

  • 是否有充分的理由不在每个 python 文件中只有一个可以从模块使用的函数?(并且与文件同名)
  • 我想,我将不得不修改我的__init__.py-files,但我不知道如何修改。

问题2的澄清

package-folder
|_ mypackage
   |_ __init__.py
   |_ module1.py #with function do_stuff1()
   |_ subpackage
      |_module2.py #with function do_stuff2()
setup.py
Run Code Online (Sandbox Code Playgroud)

调用应该是:

abbr.do_stuff1()
abbr.subpackage.do_stuff2()
Run Code Online (Sandbox Code Playgroud)

不是

abbr.module1.do_stuff1()
abbr.subpackage.module2.do_stuff2()
Run Code Online (Sandbox Code Playgroud)

Adi*_*rio 4

您已经非常接近答案了,您只需要从 导入方法即可__init__.py

您还可以添加特殊变量__all__,它是用户期望在该文件中找到的变量/函数/等的列表。

__init__.py@mypackage

from .module1 import do_stuff1

__all__ = ['do_stuff1']
Run Code Online (Sandbox Code Playgroud)

__init__.py@subpackage

from .module2 import do_stuff2

__all__ = ['do_stuff2']
Run Code Online (Sandbox Code Playgroud)

编辑:

要使您的顶级包导入所有子包符号,您可以将__init__.py@更改mypackage为:

import pkgutil

from .module1 import do_stuff1

__all__ = ['do_stuff']

for loader, name, is_pkg in  pkgutil.walk_packages(__path__):
    module = loader.find_module(name).load_module(name)
    __all__.extend(module.__all__)
    for var in module.__all__:
        globals()[var] = getattr(module, var)
Run Code Online (Sandbox Code Playgroud)

那么你不仅可以打电话abbr.subpackage.do_stuuf2(),还可以abbr.do_stuuf2()