正如目前在this question中讨论的,我正在编写内置range
和xrange
函数的包含版本。如果这些函数放在名为inclusive
的模块中,我可以看到两种可能的方法来命名函数本身:
将函数命名为inclusive_range
和inclusive_xrange
,以便客户端代码可以按如下方式使用它们:
from inclusive import *
...
inclusive_range(...)
将函数命名为
range
和xrange
:import inclusive
...
inclusive.range(...)
对我来说,客户端代码的第二个示例看起来更好,但是我应该避免以这种方式重用内置名称吗?
最佳答案
这变成了一个不同选项的列表,而不是一个直截了当的答案。然而,有两个概念至关重要:
如果用户明确选择的话,他们应该能够替换range
和xrange
;但是
用户不应隐式/意外地替换range
和xrange
;
读者应该始终清楚他们的代码在何处使用内置项以及在何处使用替换项。
因此,下面列出的所有选项都会阻止通配符导入(from inclusive import *
)隐藏内置项。对于您来说,哪一个是最好的选择取决于您是否将替换内置组件视为模块的主要用途或次要用途。用户通常是想替换内置组件,还是同时使用它们?
在你的位置上,我想我会做以下事情:inclusive.py
:
"""Inclusive versions of range and xrange."""
__all__ = [] # block 'from inclusive import *'
old_range, old_xrange = range, xrange # alias for access
def range(...): # shadow the built-in
...
def xrange(...): # ditto
...
这允许用户:
import inclusive
和访问inclusive.range
和inclusive.xrange
;from inclusive import range, xrange
,明显地替换了内置组件,没有任何不愉快的副作用;或者from inclusive import range as irange, xrange as ixrange
使用内置和替换版本。将
__all__
定义为空列表意味着from inclusive import *
不会悄悄地隐藏内置组件。如果你真的想,你可以加上:
irange, ixrange = range, xrange
在
inclusive.py
结尾处,将__all__
定义修改为:__all__ = ['irange', 'ixrange']
现在用户有两个额外的选择:
from inclusive import irange, ixrange
(比上面选项3中的手动别名功能稍微简单一些);以及from inclusive import *
(与上述结果相同,仍然没有内置的隐式阴影)。当然,您可以完全采用另一种方式-命名您自己的版本
irange
和ixrange
,然后如果用户真的想替换内置版本,他们必须:from inclusive import irange as range, ixrange as xrange
这不需要定义
__all__
来避免通配符导入隐藏内置项。