`@numba.jitclass`ed 的特殊方法去哪儿了?

Where do `@numba.jitclass`ed special methods go?

TL;DR:当用 @numba.jitclass 修饰 class 时,__add__ 等特殊方法不会出现在 class 的实例中,而其他方法正常工作.为什么会这样?

考虑以下 class 声明:

import numba as nb            

dual_spec = [('x', nb.float64), ('y', nb.float64)]                 

@nb.jitclass(dual_spec)
class xy:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def addition(self, other):
        return xy(self.x + other.x, self.y + other.y)

    def __add__(self, other):
        return xy(self.x + other.x, self.y + other.y)

没有装饰器,class 工作得很好。由于 __add__ 方法表达式 xy(1, 2) + xy(3, 4) 是可能的并且 return 预期结果。但是,使用装饰器我收到以下错误消息:

>>> xy(1, 2) + xy(3, 4)  # TypeError: unsupported operand type(s) for +: 'xy' and 'xy'
>>> xy(1, 2).addition(xy(3, 4))  # But this works nicely

xy 个对象中似乎没有 __add__ 方法:

>>> xy(1, 2).__add__  # AttributeError: 'xy' object has no attribute '__add__'

但是方法存在于class:

>>> xy.__add__  # <function __main__.xy.__add__>

numba 在实例化期间对 __add__ 方法做了什么?是否有另一种方法可以为 jitted classes 启用运算符,以便我可以编写 xy(1, 2) + xy(3, 4)?

目前(从 numba 版本 0.33 开始)不支持 jitclasses 上的运算符重载,在这里打开问题: https://github.com/numba/numba/issues/1606#issuecomment-284552746

我不知道确切的内部结构,但很可能该方法只是被丢弃了。请注意,当您在 jitclass 实例化时,您并不是直接实例化 python class 而是获取低级 numba 类型的包装器。

v = xy(1, 2)

v
Out[8]: <numba.jitclass.boxing.xy at 0x2e700274950>

v._numba_type_
Out[9]: instance.jitclass.xy#2e77d394438<x:float64,y:float64>