具有相同名称的Python模块(即,在包中重新使用标准模块名称)(Python modules wi

2019-06-24 05:53发布

假设我有一个包含模块的程序包:

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

和模块需要参考包含在彼此的功能。 好像我碰到我的问题time.py模块因为是由同一个名字去一个标准模块。

举例来说,在我的情况下foo.py模块既需要我SWS.time和标准的Python time模块,我遇到了麻烦,因为解释器会看包里面找到我time.py模块它遇到的标准前, time模块。

有没有办法解决? 这是一个没有任何情况下,应该模块的名字不被重用?

在包装理念任何解决方案的意见在这里很有用。

Answer 1:

重用标准功能/班/模块/包的名字是不是一个好主意。 尽量避免它尽可能。 但是有干净的解决方法,以你的情况。

你看,导入您的行为SWS.time代替stdlib的time ,是由于语义import古代的Python版本(2.X)。 要修复它添加:

from __future__ import absolute_import

在文件的最顶端。 这将改变的语义import到python3.x的,这是明智得多。 在这种情况下,语句:

import time

仅指向一个顶级模块。 因此解释不会考虑你的SWS.time执行包里面是进口时模块,但它只会使用标准库之一。

如果你的包一个模块需要进口SWS.time你的选择:

  • 使用一个明确的相对进口:

     from . import time 
  • 使用绝对导入:

     import SWS.time as time 

所以,你的foo.py会是这样:

from __future__ import absolute_import

import time

from . import time as SWS_time


Answer 2:

这取决于你所使用的Python版本。 如果你的目标Python版本是2.4或以上(在2015年,我当然希望没有),然后是这将是不好的做法,因为没有办法(不黑客),以区分这两个模块。

然而,在Python 2.5+,我认为一个包命名空间内重复使用标准库模块名称是完全没有问题; 其实,这是PEP328的精神 。

由于Python的库扩展,越来越多的现有封装内部组件突然意外影标准库模块。 这是内包一个特别困难的问题,因为没有办法来指定哪些模块的意思。 要解决的不确定性,所以建议foo将始终从sys.path中到达的模块或组件。 这就是所谓的绝对进口。

蟒蛇-dev的社区选择绝对导入作为默认的,因为他们是比较常见的用例,因为绝对进口可以提供相对(内包装)进口的所有功能 - 重命名包装碎片较高时在困难的成本虽然向上在层次结构或移动一个包内的另一个时。

因为这代表了语义的变化,绝对进口量将在Python 2.5和2.6可选择通过使用from __future__ import absolute_import

SWS.time显然不是一回事time和代码的读者,我希望SWS.time不仅使用time ,而是要以某种方式延长。

所以,如果SWS.foo需要进口SWS.time ,那么就应该使用绝对路径:

# 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

或者,它应该使用一个明确的相对进口在Bakuriu的回答:

# in SWS.foo

from . import time as sws_time

在你需要导入标准库的情况下time的内部模块SWS.time模块,您首先需要导入将来的功能(仅用于Python 2.5+; Python的3+默认情况下做到这一点):

# inside of SWS.time
from __future__ import absolute_import

import time

time.sleep(28800)  # time for bed

注: from __future__ import absolute_imports只会影响未来功能导入模块的import语句,并不会影响任何其他模块(如如果另一个模块依赖于相对导入,这将是有害的)。



Answer 3:

正如其他人所说,这通常是一个坏主意。

话虽这么说,如果你正在寻找可能的解决办法,还是比较了解的问题,我建议你阅读下面的SO问题:

  • 从当具有相同名称的模块存在内置库导入

  • 如何访问在Python标准库模块时,有相同名称本地模块?



Answer 4:

呀,真是周围没有很好的办法。 尽量不要命名您的模块,如标准封装。 如果你真的想打电话给你的模块time ,我推荐使用_time.py代替。 即使有办法做到这一点,它会使你的代码难以阅读和困惑,当它来到了2个模块。



文章来源: Python modules with identical names (i.e., reusing standard module names in packages)