python import module from a package

后端 未结 3 1045
执念已碎
执念已碎 2021-01-31 12:06

folder structure:


   main.py
   packages 
      __init__.py
      mod.py

main py:

3条回答
  •  遥遥无期
    2021-01-31 12:52

    Short answer

    So what does the from packages import * really mean inside that __init__.py?

    The __init__.py imports itself.

    Explanation

    You can only import modules, not packages. Packages are just containers for modules or sub-packages. When you "import" a package you actually import the module __init__.py.

    The __init__.py with this content:

    from packages import mod
    

    imports the module mod into __init__.py. Therefore, it will be available in your main.py via packages.mod (remember packages is represented by __init__.py).

    When you change the content of __init__.py to:

    from packages import *
    

    You are importing the module __init__.py, the very same file you are in. This works (a second import just triggers a lookup in sys.modules) but won't give you the content of mod.

    This means, you can use:

    from module import *
    

    but you cannot sensibly use this with an empty __init__.py:

    from package import *
    

    Because package is actually represented by the __init__.py and there is nothing in it yet. You can check this (interactively or in file):

    >>> import packages
    >>> print(packages)
    
    

    In __init__.py you can write:

    from packages.mod import *
    

    and then in main.py:

    print packages.hello()
    

    works. Because the function hello() is now in the global name space of the file __init__.py.

    As mentioned in the answer by mozman, you can use __all__ in __init__.py to list the modules that should be imported if from packages import * is used. This is designed for this case.

    The __init__.py has only this content:

    __all__ = ['mod']
    

    Now you can do this in main.py:

    from packages import *
    
    print mod.hello()
    

    If you extend your __init__.py:

    __all__ = ['mod']
    
    from packages import *
    

    You can do this in main.py:

    import packages
    
    print packages.mod.hello()
    

    But if you remove the from packages import * from __init__.py:

    __all__ = ['mod'] 
    

    You will get an error:

    AttributeError: 'module' object has no attribute 'mod'
    

    because the __all__ is only used for the from packages import * case. Now we are back to the __init__.py imports itself.

提交回复
热议问题