Hiding module imports in package

前端 未结 2 1718
深忆病人
深忆病人 2021-01-18 18:55

I have a small package that has a few dependencies such as pandas and gensim. The file structure is like so

/package
    __init__.py
    agg_clean.py
         


        
2条回答
  •  走了就别回头了
    2021-01-18 19:34

    tl;dr: You can't cleanly. Or more accurately, you shouldn't be worried about things like this.

    There's no namespace collisions in this case, since the os module is loaded under then name pkg.agg_clean.os. If the user wants to use your imported os package, there is no harm in letting them do that. On top of that, there's no good way to prevent them from doing that.

    There's something interesting to remember here. Take the following python module that can be imported by another python script:

    # module_im_importing.py
    import os as _os
    
    __all__ = ["echo"]
    
    name_not_available = 'some_constant_string'
    
    def echo(object):
        pass
    

    If your user imports the bare module using import module_im_importing, all defined variables are made available to their environment under the name module_im_importing.

    >>> import module_im_importing
    >>> dir()  # Lookup local namespace
    ['__builtins__', '__doc__', '__name__', '__package__', 'module_im_importing']
    >>> dir(module_im_importing)  # See defined items in your package.
    ['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'echo', 'name_not_available', 'os']
    

    If they instead from module_im_importing import * (which is discouraged), the behavior is a little different:

    >>> from module_im_importing import *
    >>> dir()
    ['__builtins__', '__doc__', '__name__', '__package__', 'echo']
    

    This causes the names defined in the file module_im_importing.py to be imported into the user's local namespace. Because we used __all__ in your module, only the items defined in __all__ are imported to the users local namespace from your module. This can pollute their namespace if, for example, you've defined a function like echo which conflicts with another package they may be using.

    This is why Wildcard imports are clearly frowned upon in PEP8. From the document:

    Wildcard imports (from import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.

    In any case, please don't worry yourself over things like this. It's only an issue if the user of your module doesn't follow PEP8, and they should probably be shown the errors of their ways anyway. Remember, in Python, We're all consenting adults here.

提交回复
热议问题