如何将 Python 中的模块导入到既用作 __main__ 又由不同目录中的文件导入的文件中?

How to import a module in Python in a file that is both used as a __main__ and is imported by a file in a different directory?

假设我正在使用 Python 3(因此是绝对导入)并且我的目录结构如下所示:

> package:
    > sub_directory
        __init__.py
        sub_dir_file.py
        sub_dir_file2.py
    __init__.py
    main_dir_file.py

在文件 sub_dir_file.py 中,我希望从 sub_dir_file2.py 导入一个函数。问题是,我希望能够将 运行 sub_dir_file.py__name__ == '__main__' 以及 导入 main_dir_file.py。因此,如果在 sub_dir_file.py 我使用相对导入:

from .sub_dir_file2 import some_function

当 运行 来自 main_dir_file.py 时模块执行得很好,但直接执行时会抛出错误(因为当 __name__ == '__main__' 时无法执行相对导入。但是如果我使用正常绝对导入,sub_dir_file.py 将作为 main 执行,但不能从 main_dir_file.py.

导入

解决这个问题最优雅的方法是什么?一个明显的解决方案似乎是:

if __name__ == '__main__':
    from sub_dir_file2 import some_function
else:
    from .sub_dir_file2 import some_function

然而,它似乎不是很 pythonic。

如果名称为 __main__,我建议使用 main() 调用的函数。无论如何,据我所知,这是一个好习惯。

这样你就可以自己调用导入模块的main()。它还有其他好处,比如允许您测试或重新调用模块,而不必每次都执行文件。

您应该使用相对导入语法 from .sub_dir_file2 import some_function 或最终使用绝对语法 from package.sub_directory.sub_dir_file2 import some_function

那么,为了调用其中一个package子模块,使用python解释器的-m option作为__main__模块来执行其内容更简单。

Search sys.path for the named module and execute its contents as the main module.

Since the argument is a module name, you must not give a file extension (.py). The module name should be a valid absolute Python module name, but the implementation may not always enforce this (e.g. it may allow you to use a name that includes a hyphen).

例如:

> python -m package.main_dir_file
> python -m package.sub_directory.sub_dir_file