module imports and __init__.py in Python

前端 未结 5 514
执念已碎
执念已碎 2020-12-02 15:49

I am trying to understand what the best practices are with regards to Python\'s (v2.7) import mechanics. I have a project that has started to grow a bit and lets say my code

5条回答
  •  既然无缘
    2020-12-02 16:16

    According to PEP 0008, "Public and internal interfaces":

    Imported names should always be considered an implementation detail. Other modules must not rely on indirect access to such imported names unless they are an explicitly documented part of the containing module's API, such as os.path or a package's __init__ module that exposes functionality from submodules.

    So this would suggest that it is ok to put imports in the __init__ module, if __init__ is being used to expose functions from submodules. Here is a short blog post I found with a couple examples of Pythonic uses of __init__, using imports to make subpackages available at package level.

    Your example of moving the import statements to __init__ in order to have only one import in Foo, does not seem to follow this rule. My interpretation is that the imports in your __init__ should be used for external interfaces, otherwise, just put your import statements in the file that needs them. This saves you trouble when submodule names change and keeps you from unnecessary or difficult-to-find imports when you add more files that use a different subset of submodules.

    As far as circular references, this is definitely possible in Python (for example). I wrote about that before I actually tried your toy example, but to make the example work I had to move Foo.py up a level, like so:

    Foo.py
    foo/
        __init__.py
        module1.py
        module2.py
        module3.py
    

    With that setup and some print statements, running python Foo.py gives the output:

    module 1
    module 2
    module 3
    hello Foo constructor
    

    and exits normally. Note that this is due to adding the if __name__ == "__main__" - if you add a print statement outside of that, you can see Python is still loading the module twice. A better solution would be to remove the import from your __init__.py. As I said earlier, that may or may not make sense, depending on what those submodules are.

提交回复
热议问题