<p>所发生的事情是,Python在标准库<strong>中提供了许多算法的纯Python实现,即使它包含相同算法的加速本机代码实现</p>
<p>heapq库就是其中之一——如果您选择链接到的文件,但接近结尾,您将看到代码片段,它看起来是否有本机版本,并覆盖Python版本,其中包含您复制和粘贴的代码-<a href="https://github.com/python/cpython/blob/76cd81d60310d65d01f9d7b48a8985d8ab89c8b4/Lib/heapq.py#L580" rel="nofollow noreferrer">https://github.com/python/cpython/blob/76cd81d60310d65d01f9d7b48a8985d8ab89c8b4/Lib/heapq.py#L580</a></p>
<pre><code>try:
from _heapq import *
except ImportError:
pass
...
</code></pre>
<p>本机版本的<code>heappush</code>被加载到模块中,除了获取实际的文件源代码之外,没有简单的方法可以获取对原始Python函数的引用</p>
<p>现在,重点是:为什么本机函数不能作为类方法工作?
heappush的类型是<code>builtin_function_or_method</code>,与纯Python函数的<code>function</code>相比,主要区别之一是第二种对象类型具有<code>__get__</code>方法。这个<code>__get__</code>使得Python定义的函数可以作为“描述符”工作:当从实例检索属性时,调用<code>__get__</code>方法。对于普通函数,此调用记录<code>self</code>参数,并在调用实际函数时将其注入</p>
<p>因此,编写一个“instancemethod”修饰符是很容易的,它将使内置函数作为Python函数工作,并可用作方法。但是,创建部分函数或lambda函数的开销应该超过您试图消除的额外函数调用的开销-因此您不应该从中获得速度增益,尽管它可能读起来更优雅:</p>
<pre><code>class instancemethod:
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return lambda *args, **kwargs: self.func(instance, *args, **kwargs)
import heapq
class MyHeap(list):
push = instancemethod(heapq.heappush)
</code></pre>