(Cython)在__pow__中将modulo参数设为可选

时间:2019-06-28 14:03:59

标签: python python-3.x cython pow

我正在尝试为Cython文件中的cdef class定义一些内置的算术运算。

起初,我尝试使__pow__函数像这样:

def __pow__(self, other, modulo=None):
    pass

但是在编译时收到以下错误消息:

  

此参数不能具有默认值

(错误消息引用的参数为modulo

删除modulo的默认值可以使文件正确编译,但是会强制用户提供第三个参数,这不仅很奇怪而且很烦人,而且还会阻止使用{{1} }运算符(必须改用**

如何在Cython中实现pow,使第三个参数是可选的?

2 个答案:

答案 0 :(得分:3)

您不需要为__pow__中的第三个参数分配默认值:cython会为您完成此操作。当仅使用2个参数使用**运算符或pow()时,第三个参数设置为None。然后,如果您不打算处理None的3参数形式,则可以显式检查return NotImplementedpow

一个简单的示例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):
       ...
相关问题