在cython的增强纯python中定义classmethod

时间:2016-10-04 07:23:28

标签: python cython class-method

在python中,我使用classmethods作为工厂函数,例如拆分URI并构造适当的(子)类实例。但是,当尝试通过augmenting pxd将其移植到Cython时,这不起作用。将类定义为cdef class会给出以下错误:

TypeError: descriptor '<class method name>' of '<cdef class type>' object needs an argument

最小(不是)工作示例:

考虑定义:

# cy.py
class Foo(object):
    def imeth(self):
        print('i', self)

    @classmethod
    def cmeth(cls):
        print('c', cls)

在python中运行它可以正常工作:

ipython -c 'import cy; cy.Foo().imeth(); cy.Foo().cmeth(); cy.Foo.cmeth()'
('i', <cy.Foo object at 0x100652d50>)  # method on instance
('c', <class 'cy.Foo'>)  # class method on instance
('c', <class 'cy.Foo'>)  # class method on class

只需打开Cython也可以:

ipython -c 'import pyximport; pyximport.install(pyimport = True);import cy; cy.Foo().imeth(); cy.Foo().cmeth(); cy.Foo.cmeth()'
# compiler warnings about unused functions
('i', <cy.Foo object at 0x10b8d7f28>)  # method on instance
('c', <class 'cy.Foo'>)  # class method on instance
('c', <class 'cy.Foo'>)  # class method on class

现在,为pxd定义添加cdef class后......

# cy.pxd
cdef class Foo:
    cpdef imeth(self)
    cpdef cmeth(cls)

...使用Cython(清除缓存后)不再有效:

ipython -c 'import pyximport; print(pyximport.install(pyimport = True));import cy;cy.Foo().imeth(); cy.Foo().cmeth(); cy.Foo.cmeth()'
# compiler warnings about unused functions
i <cy.Foo object at 0x10b742510>
c <cy.Foo object at 0x10b742510>
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-ede0f6764b14> in <module>()
----> 1 import pyximport; print(pyximport.install(pyimport = True));import cy; print(cy);cy.Foo().imeth(); cy.Foo().cmeth(); cy.Foo.cmeth()

TypeError: descriptor 'cmeth' of 'cy.Foo' object needs an argument

第二个输出行显示Foo.cmeth基本上忽略了classmethod装饰器。但我似乎无法在pxd中应用它。这可以通过pxd首先实现吗?

0 个答案:

没有答案