我正在尝试测试并修复a bug in pprint++(编辑:the correct link; original link left for posterity)即将到来,因为instancemethod
类型不可用:
In [16]: import pandas as pd
In [17]: type(pd.tslib.NaT).__repr__
Out[17]: <instancemethod __repr__ at 0x1058d2be8>
In [18]: hash(type(pd.tslib.NaT).__repr__)
...
TypeError: unhashable type: 'instancemethod'
但是我在测试这个问题时遇到了麻烦,因为我不知道在Python 3标准库中我还能在哪里找到instancemethod
,而且我不希望我的测试依赖于Pandas。
具体来说,似乎“普通”内置类型的“实例方法”实现方式略有不同:
In [19]: type(None).__repr__
Out[19]: <slot wrapper '__repr__' of 'NoneType' objects>
In [20]: hash(type(None).__repr__)
Out[20]: -9223372036583849574
那么:我在哪里可以在Python 3标准库中找到instancemethod
,以便我可以针对它编写测试?或者它是不是出现在那里的特殊类型?
(注意:这只会影响Python 3,因为Python 2中的同一方法是unbound method
,可以清除)
答案 0 :(得分:4)
此类型不用于Python附带的任何内容,并且没有用于创建此类对象的Python级API。但是,您可以使用直接C API调用来执行此操作:
import ctypes
PyInstanceMethod_New = ctypes.pythonapi.PyInstanceMethod_New
PyInstanceMethod_New.argtypes = (ctypes.py_object,)
PyInstanceMethod_New.restype = ctypes.py_object
arbitrary_callable = sum
instance_method = PyInstanceMethod_New(arbitrary_callable)
名称instancemethod
看起来很像一个绑定的方法对象,但事实证明它完全是另一回事。根据它的documentation,它是一种奇怪的内部事物,它应该是C类型表示其方法的新方法,除了用于创建类型的标准C级API实际上不使用它。
根据Python问题跟踪器上的conversations,Cython和Pyrex的开发人员要求使用此功能。看起来pandas.tslib.NaT
在Cython中实现,而Cython实现实际上使用了这种类型,其中用于创建类型的标准C API没有。
请注意,Python 2的情况完全不同。在Python 2中,这种新类型不存在,instancemethod
是表示用Python编写的普通方法的方法对象类型的名称。在Python 3中,新类型使用该名称,并且用Python编写的方法的方法对象类型现在命名为method
。
答案 1 :(得分:2)
Python提供它,但基本上只作为他们的测试套件AFAICT的一部分(否则包括电池使用它)。您可以使用_testcapi
模块进行测试:
>>> import _testcapi
>>> testinstancemethod = _testcapi.instancemethod(str.__repr__)
>>> hash(testinstancemethod)
...
TypeError: unhashable type: 'instancemethod'