Can someone explain __all__ in Python?

前端 未结 11 2456
一个人的身影
一个人的身影 2020-11-21 13:36

I have been using Python more and more, and I keep seeing the variable __all__ set in different __init__.py files. Can someone explain what this d

11条回答
  •  春和景丽
    2020-11-21 13:51

    __all__ customizes * in from import *

    __all__ customizes * in from import *


    A module is a .py file meant to be imported.

    A package is a directory with a __init__.py file. A package usually contains modules.


    MODULES

    """ cheese.py - an example module """
    
    __all__ = ['swiss', 'cheddar']
    
    swiss = 4.99
    cheddar = 3.99
    gouda = 10.99
    

    __all__ lets humans know the "public" features of a module.[@AaronHall] Also, pydoc recognizes them.[@Longpoke]

    from module import *

    See how swiss and cheddar are brought into the local namespace, but not gouda:

    >>> from cheese import *
    >>> swiss, cheddar
    (4.99, 3.99)
    >>> gouda
    Traceback (most recent call last):
      File "", line 1, in 
    NameError: name 'gouda' is not defined
    

    Without __all__, any symbol (that doesn't start with an underscore) would have been available.


    Imports without * are not affected by __all__


    import module

    >>> import cheese
    >>> cheese.swiss, cheese.cheddar, cheese.gouda
    (4.99, 3.99, 10.99)
    

    from module import names

    >>> from cheese import swiss, cheddar, gouda
    >>> swiss, cheddar, gouda
    (4.99, 3.99, 10.99)
    

    import module as localname

    >>> import cheese as ch
    >>> ch.swiss, ch.cheddar, ch.gouda
    (4.99, 3.99, 10.99)
    

    PACKAGES

    In the __init__.py file of a package __all__ is a list of strings with the names of public modules or other objects. Those features are available to wildcard imports. As with modules, __all__ customizes the * when wildcard-importing from the package.[@MartinStettner]

    Here's an excerpt from the Python MySQL Connector __init__.py:

    __all__ = [
        'MySQLConnection', 'Connect', 'custom_error_exception',
    
        # Some useful constants
        'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
        'HAVE_CEXT',
    
        # Error handling
        'Error', 'Warning',
    
        ...etc...
    
        ]
    

    The default case, asterisk with no __all__ for a package, is complicated, because the obvious behavior would be expensive: to use the file system to search for all modules in the package. Instead, in my reading of the docs, only the objects defined in __init__.py are imported:

    If __all__ is not defined, the statement from sound.effects import * does not import all submodules from the package sound.effects into the current namespace; it only ensures that the package sound.effects has been imported (possibly running any initialization code in __init__.py) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by __init__.py. It also includes any submodules of the package that were explicitly loaded by previous import statements.


    Wildcard imports ... should be avoided as they [confuse] readers and many automated tools.

    [PEP 8, @ToolmakerSteve]

提交回复
热议问题