首页 > 解决方案 > 相对导入:子包导入子包

问题描述

目录结构:

root/
   script.py
   package/
      __init__.py
      module1.py
      module2.py

script.py我需要从中导入一个方法module1.py并运行它。

#contents of script.py 
from package.module1 import func1

func1()

中的方法module1.py需要来自 的方法module2.py

#contents of module1.py 
from package.module2 import func2

def func1():
    func2()

if __name__ == "__main__":
     func1()

如果我直接运行,上面的代码就可以工作script.py。但是,在某些情况下,我需要module1.py直接运行crontab,这就是问题所在。

当 cronjob 运行时,我收到一条错误消息,说func2找不到。module1.py如果我将导入修改为以下内容,我可以运行:

#contents of module1.py 
from module2 import func2

def func1():
    func2()

if __name__ == "__main__":
     func1()

如果我添加一个else语句,我可以使这两种情况都起作用,module1.py但它看起来很老套:

#contents of module1.py 

def func1():
    func2()

if __name__ == "__main__":
    from module2 import func2 
    func1()
else:
    from package.module2 import func2
    func1()

我怎样才能更蟒蛇地做到这一点?也许我需要以__init__.py某种方式利用?目前只是一个空文件。

标签: pythonpython-importrelative-path

解决方案


使用python file.pypython运行文件时,不会查看包含filefor的目录__init__.py。这意味着您不能使用import package.module也不能from .module import x导入。

解决这个问题的方法是告诉 python 它file.py是包的一部分。这是通过使用-m开关完成的:

python -m package.module1

所以你不必修复你的代码,你必须修复你的crontab命令!


这就是说:我个人从不喜欢运行模块。我宁愿run_module1.py在包外写一个脚本,它只包含:

from package import module1
module1.func1()

然后运行run_module1.py而不是module1.py直接运行。

我不认为有任何充分的理由想要module1.py像你一样运行并期望它在你尝试过的没有 hacky 导入的情况下工作。AFAIK 对此没有非骇客的解决方案。


推荐阅读