我正在尝试为Cython文件中的cdef class
定义一些内置的算术运算。
起初,我尝试使__pow__
函数像这样:
def __pow__(self, other, modulo=None):
pass
但是在编译时收到以下错误消息:
此参数不能具有默认值
(错误消息引用的参数为modulo
)
删除modulo
的默认值可以使文件正确编译,但是会强制用户提供第三个参数,这不仅很奇怪而且很烦人,而且还会阻止使用{{1} }运算符(必须改用**
。
如何在Cython中实现pow
,使第三个参数是可选的?
答案 0 :(得分:3)
您不需要为__pow__
中的第三个参数分配默认值:cython会为您完成此操作。当仅使用2个参数使用**
运算符或pow()
时,第三个参数设置为None
。然后,如果您不打算处理None
的3参数形式,则可以显式检查return NotImplemented
和pow
。
一个简单的示例cython类,位于_cclass_test.pyx中:
# cython: language_level=3
cdef class Test:
def __pow__(x, y, z):
if z is None:
print("Called with just x and y")
else:
print("Called with x, y and z")
及其使用示例:
import pyximport
pyximport.install()
from _cclass_test import Test
t = Test()
t ** 5
pow(t, 5)
pow(t, 5, 3)
输出:
$ python cclass_test.py
Called with just x and y
Called with just x and y
Called with x, y and z
(使用Cython 0.29.12版进行了测试)
答案 1 :(得分:1)
您可以使用装饰器欺骗cython编译器以使其认为该参数没有默认值:
def trickster(func):
def wrapper(self, other, modulo=None):
return func(self, other, modulo)
return wrapper
class MyClass:
...
@trickster
def __pow__(self, other, modulo):
...