只是为了给 @Warren Weckesser 的答案增添一些我的五分钱。真正的情况是,from numpy import *
并没有覆盖内置函数 sum
,它只是遮蔽了 __builtins__.sum
,因为 from ... import *
语句将导入模块中定义的除下划线开头的所有名称绑定到当前的 global
命名空间中。根据 Python 的名称解析规则 (非官方的 LEGB 规则),Python 会先在你的 global
命名空间中查找,然后才会在 __builtins__
命名空间中查找。所以如果 Python 找到所需的名称,在这种情况下是 sum
,它就会返回绑定的对象,而不会再往下查找。
编辑:
为了向你展示发生了什么:
In[1]: print(sum, ' from ', sum.__module__)
Out[1]: <built-in function sum> from builtins
In[2]: from numpy import *
print(sum, ' from ', sum.__module__)
Out[2]: <function sum at 0x00000229B30E2730> from numpy.core.fromnumeric
In[3]: del sum
print(sum, ' from ', sum.__module__)
Out[3]: <built-in function sum> from builtins
第一条注意事项: del
不会删除对象,这是垃圾收集器的任务,它只是“取消引用”名称绑定并从当前命名空间中删除名称。
第二个注意事项:内置函数sum
的签名为sum(iterable[, start])
:
从左到右对iterable
的项目及 start
进行求和,并返回总和。start
默认为 0 。可迭代的项目通常是数字,而不允许将字符串用作起始值。
在您的情况下,对于内置的sum
,print(sum(range(5),-1)
将以 -1 开始进行求和。 因此,在技术上,您的短语通过对可迭代项求和然后从总和减去第二个参数的值不正确。 对于数字,真正要紧的是是否以某个值开始或者稍后添加/相加/相减。 但是对于列表来说,则有所不同(仅是愚蠢的示例,仅用于说明这个想法):
In[1]: sum([[1], [2], [3]], [4])
Out[1]: [4, 1, 2, 3] # not [1, 2, 3, 4]
希望这能澄清您的想法 :)
Hope this will clarify your thoughts :)
np.sum
与内置的sum
是不同的——所以如果你不小心,*
可能会很危险。 - hpaulj