相对导入:subpackage 导入子包

Relative imports: subpackage importing subpackage

目录结构:

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,上面的代码就可以工作。但是,在某些情况下,我需要直接通过 crontab 运行 module1.py,这就是问题所在。

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

#contents of module1.py 
from module2 import func2

def func1():
    func2()

if __name__ == "__main__":
     func1()

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

#contents of module1.py 

def func1():
    func2()

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

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

当 运行使用 python file.py python 连接文件时 不会 查看包含 file 的目录 __init__.py。这意味着您不能使用 import package.modulefrom .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 对此没有非 hackish 解决方案。