提取和隔离 Python 函数,给定 class 的实例

Extracting and isolating a Python function, given an instance of a class

假设我得到一个 Python class 的实例。这个 class 有一个函数,我想从 class 中提取和隔离它。最终函数需要访问原始 class 中的属性值,否则它根本不应该调用 class。

我的动机是我想使用 numba 中的 jit 编译函数,但我不想使用 jitclass[= 编译整个 class 19=]

作为具体示例,请考虑以下 class。理想情况下,我不想修改这段代码:

class Adder:
    """
    A minimal callable class with keyword arg
    """
    def __init__(self, num=4):
        self.num = num
    def add(self, val1, val2):
        return val1 + val2
    def add_default(self, val1, val2):
        return self.num + val1 + val2

我现在实例化这些对象,然后尝试使用 numba 编译它们的方法。这在实例方法不使用任何对象的属性时有效

from numba import jit

a = Adder(num=1)
print(a.add(7, 8)) # 15
add_fast = jit(a.add)
print(add_fast(7, 8)) # 15

但是,当我尝试使用需要 class 属性的方法时,这会中断

from numba import jit

a = Adder(num=1)
print(a.add_default(7, 8)) # 16
add_default_fast = jit(a.add_default)
print(add_default_fast(7, 8)) # NotDefinedError: Variable 'self' is not defined.

我尝试使用 lambda 函数,但它仍然在内部引用 class 并破坏了 jit。理想情况下,我想提取实例方法以及所有实例属性的值,并构建一个新函数,用实例属性中的值替换所有 self. 变量。

有没有简单的方法可以做到这一点?我希望有一个不涉及重构 class.

的解决方案

试试这个:

def add_default(a,*args):
    return Adder.__dict__['add_default'](a,*args)

add_default_fast = jit(add_default,forceobj=True)
print(add_default_fast(a,7, 8)) # 16

您可以将任何具有 'num' 属性的 python 对象传递给函数

而不是 'a'

(另请参阅:Python: Hack to call a method on an object that isn't of its class 中的 dict 技巧,它允许显式指定方法的 'self' 参数)