【问题标题】:Making a python3 package both importable and runnable使 python3 包既可导入又可运行
【发布时间】:2018-09-03 19:48:56
【问题描述】:

我正在将一些旧脚本从 python v2.7 过渡到 v3.6,我想做的一件事是有一个可以 (a) 导入以将内部工作暴露给其他脚本的包,但是也 (b) 可以从命令行运行,以典型方式运行。

在 python2 中这并不难——我同时使用了 __init__.py 文件(用于导入)和 __main__.py 文件(用于运行)。但是在python3中,这似乎不起作用——例如,采取最小包:

minimal/
  __init.py__
  __main.py__
  func.py
  func2.py

__init__.py

from .func import f
from .func2 import add2

__main__.py

from func import f
f(1)

func.py

from .func2 import add2
def f(x):
  print(add2(x))

func2.py

def add2(x):
  return x + 2

如果我打开 python 并输入 import minimal 这很好,但如果我从命令行输入 python minimal/ 我会收到错误:

ImportError: attempted relative import with no known parent package

这出现在 func.py 的第 1 行,位于 func2 的 import。如果我改为从该行中删除句点,而是改为from func2 import add2,那么我可以从命令行运行python minimal/ 就好了。但是当我尝试打开 python 并运行import minimal 时,在同一行出现错误:

ModuleNotFoundError: No module named 'func2'

我知道包内导入需要这个时间段,但是有什么方法可以在主脚本中进行这项工作吗?或者其他允许导入和运行的包结构?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    将您的项目结构更改为:

    minimal_cmd/
    ├── __main__.py
    └── minimal
        ├── __init__.py
        ├── func.py
        └── func2.py
    

    并在__main__.py 中进行完全限定的导入:

    if __name__ == '__main__':
    
        from minimal.func import f
    
        f(1)
    

    从命令行调用:

    $ python minimal_cmd
    3
    

    minimal 是当前工作目录或者包在 PYTHONPATH 上时导入:

    >>> import minimal
    >>> minimal.f(2)
    4
    

    【讨论】:

    • 有点...这意味着我不能拥有一个既可以运行又可以导入的包,但似乎将主要功能移出是唯一可行的解​​决方法。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2021-07-26
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 1970-01-01
    相关资源
    最近更新 更多