【问题标题】:Extracting and isolating a Python function, given an instance of a class给定类的实例,提取和隔离 Python 函数
【发布时间】:2020-05-28 23:42:40
【问题描述】:

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

我的动机是我想使用numba 中的jit 编译函数,但我不想使用jitclass 编译整个类

作为一个具体的例子,考虑下面的类。理想情况下,我不想修改此代码:

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

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

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 函数,但它仍然在内部引用该类并中断 jit。理想情况下,我想提取实例方法以及所有实例属性的值,并构建一个新函数,将所有self. 变量替换为其实例属性中的值。

有没有简单的方法来做到这一点?我希望有一个不涉及重构类的解决方案。

【问题讨论】:

    标签: python oop instance-variables numba


    【解决方案1】:

    试试这个:

    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”参数)

    【讨论】:

    • 谢谢,我接受了,因为它有效。但是,我注意到它的运行速度比未编译版本慢。我认为这是因为(如果我理解正确的话)它会在每次调用 add_default 时实例化一个新的 Adder。如果有办法完全隔离函数就好了,但我知道这可能是不可能的。
    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多