如何通过在njit函数中引用它来修改类属性?

时间:2018-03-27 09:10:44

标签: python class reference numba

我想更新njit函数中的class属性,但我事先并不知道变量名。为了说明这一点,我制作了以下代码

from numba import jitclass, jit, njit
from numba import int32, float64
import numpy as np

spec = [('A' ,float64),
        ('B' ,float64)]

@jitclass(spec, )
class myClass():
    def __init__(self):
        self.A = 1.
        self.B = 1.
    def add_A_and_B(self):
        return self.A + self.B

class essai():
    def __init__(self):
        self.C = myClass()

    def compute(self):
        mystring = 'C.A' # parameter that I want update
        nameclass, nameparam = mystring.split('.') # get the class name and the variable to update
        tp = np.linspace(0, 100, num = 101)
        val_A = np.linspace(0, 100, num = 101)
        ref = getattr(getattr(self,nameclass),nameparam) # Doesn't work, trying to get a reference to a class attribute C.A
        y= solve1(self.C,tp,ref,val_A) # pass the reference to the njit function to update C.A in the njit function
        print(y)


@njit(fastmath=True)
def solve1(C,tp,param,paramvalues):
    y = np.zeros(len(tp), )
    for idx, t in enumerate(tp):
        param=paramvalues[idx]
        #C.A=paramvalues[idx] # what I expect the previous line to do
        y[idx] = C.add_A_and_B()
    return y

E=essai()
E.compute()

我想要更新的变量是mystring = 'C.A',但在我的完整代码中,这来自用户输入。所以我想要做的是获取该变量的引用,我尝试了ref = getattr(getattr(self,nameclass),nameparam)但是这不起作用。一旦我将获得此引用,我将能够将其传递给solve1 njit函数,以便在C.A函数内更新njit。 所以我运行我得到的代码

[ 2.  2.  2.  2.  2.  2.

而不是

[   1.    2.    3.    4.    5. .... 

如果我在C.A=paramvalues[idx]函数中使用solve1

所以问题是如何通过使用包含我想要更新的变量名称的字符串来更新A函数内C的属性njit(在我的案例mystring = 'C.A'

1 个答案:

答案 0 :(得分:1)

1)引用,因为你希望能够在这里使用它直接分配给它(param=...)在python中不存在。分配给没有点或[]修饰符的左值总是重新绑定该名称,无论是否为numba。编辑:澄清,如果名称标有global(对全局变量)或nonlocal(对于已关闭的变量),则不是真的,但这里都不适用。

2)在nopython模式下,numba需要在编译时知道你要分配的属性(它本质上是计算偏移到ac结构中),所以我认为你能做的最好的就是编译两个版本的功能。