可以重用Python内置函数的名称吗?

时间:2015-04-18 09:07:39

标签: python naming-conventions

正如this question目前正在讨论的那样,我正在编写内置rangexrange函数的包容性版本。如果将它们放在名为inclusive的模块中,我会看到两种可能的方法来命名函数本身:

  1. 将函数命名为inclusive_rangeinclusive_xrange,以便客户端代码可以按如下方式使用它们:

    from inclusive import *
    ...
    inclusive_range(...)
    
  2. 将函数命名为rangexrange

    import inclusive
    ...
    inclusive.range(...)
    
  3. 对我而言,客户端代码的第二个示例看起来更好,但是我应该避免以这种方式重复使用内置名称吗?

4 个答案:

答案 0 :(得分:4)

这变成了一些不同选项的列表,而不是直接的答案。但是,有两个概念是最重要的:

  • 用户应该能够替换rangexrange ,如果他们明确选择;但
  • 用户不应隐式/意外替换 rangexrange;

读者应始终清楚使用内置插件的代码以及使用替换的位置。

出于这个原因,我在下面列出的所有选项阻止通配符导入(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
    ...

这允许用户:

  1. import inclusive并访问inclusive.rangeinclusive.xrange;
  2. from inclusive import range, xrange,明显更换内置插件,没有任何不愉快的副作用;或
  3. from inclusive import range as irange, xrange as ixrange将内置版本和替换版本并排使用。
  4. __all__定义为空列表意味着from inclusive import * 不会静静地隐藏内置插件。


    如果真的想要,你可以添加:

    irange, ixrange = range, xrange
    

    inclusive.py的末尾,并将__all__定义修改为:

    __all__ = ['irange', 'ixrange']
    

    现在,用户还有两个选择:

    • from inclusive import irange, ixrange(比上面选项3中的手动别名功能稍微简单一些);和
    • from inclusive import *(与上面相同的结果,仍然没有隐含的内置阴影)。

    当然,您可以完全采用其他方式 - 命名您自己的版本irangeixrange,然后如果用户确实希望替换内置版本必须:

    from inclusive import irange as range, ixrange as xrange
    

    这不需要您定义__all__以避免通配符导入遮蔽内置插件。

答案 1 :(得分:0)

您应该避免以这种方式重用内置函数名称,因为这可能会破坏您所依赖的任何库,并且对于其他人(或将来您)来说非常混淆以进行读取和维护。但是,如果必须,可以选择执行此操作。

答案 2 :(得分:0)

你可以,但这可能不是一个好主意。

问题是,如果其他人使用该库,他们可能会引入副作用

 from your_lib import inclusive range

 ..... lots of code .....

 range()    # ambiguous 

答案 3 :(得分:0)

这里的问题是,在您的模块中,您将无法调用内置range()xrange()。您描述inclusive.range()的方式看起来不错,但任何其他用户可能无法以相同方式导入,并且他们也会遇到冲突。

inclusive.irange()inclusive.ixrange()呢?

编辑:如果你注意导入并重命名它们,你可以在你自己的模块中使用range(),但这可能是另一个迹象,这是一个潜在的棘手的方法。