Python modules with identical names (i.e., reusing standard module names in packages)

后端 未结 4 1114
死守一世寂寞
死守一世寂寞 2020-12-03 07:38

Suppose I have a package that contains modules:

SWS/
  __init.py__
  foo.py
  bar.py
  time.py

and the modules need to refer to functions c

4条回答
  •  庸人自扰
    2020-12-03 08:02

    It depends on what version of Python you're using. If your targeted Python version is 2.4 or older (in 2015, I sure hope not), then yes it would be bad practice as there is no way (without hacks) to differentiate the two modules.

    However, in Python 2.5+, I think that reusing standard lib module names within a package namespace is perfectly fine; in fact, that is the spirit of PEP328.

    As Python's library expands, more and more existing package internal modules suddenly shadow standard library modules by accident. It's a particularly difficult problem inside packages because there's no way to specify which module is meant. To resolve the ambiguity, it is proposed that foo will always be a module or package reachable from sys.path . This is called an absolute import.

    The python-dev community chose absolute imports as the default because they're the more common use case and because absolute imports can provide all the functionality of relative (intra-package) imports -- albeit at the cost of difficulty when renaming package pieces higher up in the hierarchy or when moving one package inside another.

    Because this represents a change in semantics, absolute imports will be optional in Python 2.5 and 2.6 through the use of from __future__ import absolute_import

    SWS.time is clearly not the same thing as time and as a reader of the code, I would expect SWS.time to not only use time, but to extend it in some way.

    So, if SWS.foo needs to import SWS.time, then it should use the absolute path:

    # in SWS.foo
    
    # I would suggest renaming *within*
    # modules that use SWS.time so that
    # readers of your code aren't confused
    # with which time module you're using
    from SWS import time as sws_time
    

    Or, it should use an explicit relative import as in Bakuriu's answer:

    # in SWS.foo
    
    from . import time as sws_time
    

    In the case that you need to import the standard lib time module within the SWS.time module, you will first need to import the future feature (only for Python 2.5+; Python 3+ does this by default):

    # inside of SWS.time
    from __future__ import absolute_import
    
    import time
    
    time.sleep(28800)  # time for bed
    

    Note: from __future__ import absolute_imports will only affect import statements within the module that the future feature is imported and will not affect any other module (as that would be detrimental if another module depends on relative imports).

提交回复
热议问题