如何在python/C中比较unbound instancemethod equality

2024-04-25 18:14:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试将一些Python2.7类移植到一个C扩展模块中——实际上是D,但这在这里并不重要。你知道吗

我的一个类提供了richcompare,对于richcompare,如果两个对象的某个类型的方法是相同的(某些C属性中的appart),那么两个对象应该进行相等的比较。例如,所需的行为将是(让mytype是提供richcompare的类型,“method”是需要比较的instancemethod的名称):

class X(mytype) :
    def method(self) : pass

class Y(X) :
    pass

class Z(X) :
    def method(self) : pass

x=X(); y=Y(); z=Z()

x==y # True
x==z # False

我试图通过比较从中返回的PyObject*指针在C中实现这个测试

auto self_type = cast(PyObject*) py_self.ob_type;
auto other_type = cast(PyObject*) py_other.ob_type;
PyObject* self_method = PyObject_GetAttrString(self_type, "method");
PyObject* other_method = PyObject_GetAttrString(other_type, "method");

if (self_method != other_method) equal = false;

Py_XDECREF(self_method);
Py_XDECREF(other_method);

令我惊讶的是,即使TypeObjects是相等的,两个指针也不相等。你知道吗

然后我签入了纯python,事实上:

Python 2.7.12+ (default, Sep 17 2016, 12:08:02) 
[GCC 6.2.0 20160914] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class X(object) :
...     def method(self) : pass
... 
>>> x=X()
>>> type(x).method == X.method
True
>>> type(x).method is X.method
False
>>> 

返回的方法不相同。所以,我有两个问题:

1)为什么非绑定方法X.method不相同?你知道吗

2)如何使用C API测试它们的相等性?你知道吗


Tags: 对象方法selffalsetrue类型deftype
1条回答
网友
1楼 · 发布于 2024-04-25 18:14:45

我现在解决了。你知道吗

1)方法查找似乎创建了一个新对象,将python函数包装到一个新对象中。这就是为什么

X.method is X.method

返回False。你知道吗

2)PyMethod\u函数(method)可用于从method对象获取函数(PyObject*)。这确实实现了预期的行为:

auto self_type = cast(PyObject*) py_self.ob_type;
auto other_type = cast(PyObject*) py_other.ob_type;
PyObject* self_method = PyObject_GetAttrString(self_type, "propensity");
PyObject* other_method = PyObject_GetAttrString(other_type, "propensity");
if (PyMethod_Function(self_method != PyMethod_Function(other_method))
    equal = false;
Py_XDECREF(self_method);
Py_XDECREF(other_method);

健壮的代码应该在获取PyMethods的函数之前检查它们各自的属性是否确实是PyMethods。你知道吗

相关问题 更多 >