(Cython) 在 __pow__

问题描述 投票:0回答:3

我正在尝试为 Cython 文件中的

cdef class
定义一些内置算术运算。

起初我尝试像这样制作

__pow__
函数:

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

但是编译时收到如下错误信息:

该参数不能有默认值

(错误消息引用的参数是

modulo

删除

modulo
的默认值允许文件正确编译,但强制用户提供第三个参数,这不仅奇怪且烦人,而且还阻止使用
**
运算符 (
pow
必须使用)。

如何在 Cython 中实现

__pow__
以使第三个参数是可选的?

python python-3.x cython pow
3个回答
3
投票

您不需要为

__pow__
中的第三个参数分配默认值:cython 会为您完成此操作。当仅使用 2 个参数的
**
运算符或
pow()
时,第三个参数设置为
None
。如果您不打算处理 3 参数形式的
None
,则可以显式检查
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
投票

您可以使用装饰器来欺骗 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):
       ...

0
投票

在较新版本的 Cython 中,您的代码将按原样接受。

参见 [BUG]

__pow__
所需的参数数量阻止编译和解释纯 python 代码兼容性 · 问题 #5160 · cython/cython

当然,如果最后一个参数的默认值不是

None
,Cython 仍然会抱怨。理应如此。

(如果您确实想要非

None
默认参数,您可以检查
None
并进行相应替换)

© www.soinside.com 2019 - 2024. All rights reserved.