<blockquote>
<p>I just realized I can simply implement <code>__get__</code> and return a <code>types.MethodType</code>, but I don't really understand how doing so still enables you to call empty_function. </p>
</blockquote>
<p>这是因为<code>MethodType</code>有一个<code>__getattribute__</code>方法,该方法将未知属性委托给其<code>im_func</code>:</p>
<pre><code>>>> t.dosomething
<bound method Test.? of <__main__.Test object at 0x107639550>>
>>> 'empty_function' in dir(t.dosomething)
False
>>> t.dosomething.__getattribute__
<method-wrapper '__getattribute__' of instancemethod object at 0x109583aa0>
>>> t.dosomething.__getattribute__('empty_function')
<bound method FunctionFaker.empty_function of <__main__.FunctionFaker object at 0x1095f2510>>
</code></pre>
<p>当然,在CPython中,capi并没有完全反映出<code>__getattribute__</code>和{<cd5>}之间的Python级别的区别,因此它的<em>真正的</em>实现方式是使用一个定制的<a href="https://docs.python.org/2/c-api/typeobj.html#c.PyTypeObject.tp_getattro" rel="nofollow">^{<cd6>}</a>槽。您可以阅读详细信息<a href="https://hg.python.org/cpython/file/2.7/Objects/classobject.c#l2298" rel="nofollow">in the source</a>。在</p>
<blockquote>
<p>Does it simply become an attribute of the <code>MethodType</code> instance? </p>
</blockquote>
<p>是的,但只是动态的,通过给你底层可调用的属性。在</p>
<p>我不认为它们是专门打算用类实例来代替具有自己的方法描述符的函数。但即使是将属性附加到方法的简单情况,也需要这种支持。例如,对于一个独立的函数,您可以使用函数属性,例如,记忆缓存,或延迟初始化第一次调用设置。如果<code>MethodType</code>没有将属性访问委托给它的<code>im_func</code>对象,那么将这样一个函数移动到一个类中会破坏它,并且开发人员将无法修复它,除非他知道描述符是如何工作的,并且以一种难看的方式重写了方法。在</p>
<p>事实上,在2.3之前,方法甚至没有<code>__dict__</code>;正如您从<a href="https://hg.python.org/cpython/file/2.3/Objects/classobject.c#l2143" rel="nofollow">the source</a>看到的那样,<em>除了C槽之外的所有属性都被委托给<code>im_func</code>(通过有效地复制正常的机制,将所有的东西都委托给<code>im_func</code>,但会出现包装错误)。关于这个问题有一些争论,你可以通过搜索python dev档案找到christismer在2.4之前的时期发表的一篇文章,文章主题相关(可能是<a href="https://mail.python.org/pipermail/python-dev/2003-November/040301.html" rel="nofollow">this thread</a>,但我没有读到全部内容…)。从2.4开始,方法现在执行正常的查找机制(除了<code>__doc__</code>的特殊情况),并且只有在失败时才委托给<code>im_func</code>。在</p>
<blockquote>
<p>And is this a sane thing to do?</p>
</blockquote>
<p>这有点奇怪,<em>也许</em>将<code>empty_function</code>属性添加到function对象中会更简单,而不是将其包装在一个类中……但我认为这并不太合理。(我假设您询问的是您的代码,而不是<code>MethodType</code>和描述符是如何实现的。)</p>