简体   繁体   中英

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?

Say I am using Python 3 (and hence absolute imports) and my directory structure looks like this:

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

In the file sub_dir_file.py I wish to import a function from sub_dir_file2.py . The catch is, I want to be able to run sub_dir_file.py with __name__ == '__main__' , as well as import it in main_dir_file.py . Hence, if in sub_dir_file.py I use a relative import:

from .sub_dir_file2 import some_function

the module executes perfectly fine when run from main_dir_file.py , but throws an error when executed directly (as the relative import cannot be executed when __name__ == '__main__' . If I however use a normal absolute import, sub_dir_file.py will execute as a main, but cannot be imported from main_dir_file.py .

What would be the most elegant way of solving this problem? One obvious solution seems to be:

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

However, it doesn't seem very pythonic.

I would suggest using a main() function invoked if name is __main__ . It's a good habit anyway, as far as I'm aware.

That way you can just call the imported module's main() yourself. It has other benefits, too, like allowing you to test or re-invoke the module without necessarily executing the file every time.

You should use the relative import syntax from .sub_dir_file2 import some_function or eventually the absolute syntax from package.sub_directory.sub_dir_file2 import some_function .

Then, in order to call one of the package sub module, it is simpler to use the -m option of the python interpreter to execute its content as the __main__ module.

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 (eg it may allow you to use a name that includes a hyphen).

For example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM