如何通过在 njit 函数中引用它来修改 class 属性?
How modify a class attribute through a reference of it in njit function?
我想更新 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
函数,以便更新 njit
函数内的 C.A
。
所以我 运行 我得到的代码
[ 2. 2. 2. 2. 2. 2.
而不是
[ 1. 2. 3. 4. 5. ....
如果我在 solve1
函数中使用 C.A=paramvalues[idx]
。
所以问题是如何使用包含我要更新的变量名称的字符串在 njit
函数中更新 C
的属性 A
(就我而言 mystring = 'C.A'
)
1) 引用,因为您希望能够通过直接分配给它在这里使用它 (param=...
) python 中不存在。分配给没有点或 [] 修饰符的左值总是重新绑定该名称,无论是否在 numba 中。编辑:澄清一下,如果名称标有 global
(对全局变量)或 nonlocal
(对封闭变量)则不正确,但均不适用于此处。
2) 在 nopython 模式下,numba 需要在编译时知道你要分配给哪个属性(它本质上是计算 c 结构的偏移量),所以我认为你能做到的最好要做的是编译两个版本的函数。
我想更新 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
函数,以便更新 njit
函数内的 C.A
。
所以我 运行 我得到的代码
[ 2. 2. 2. 2. 2. 2.
而不是
[ 1. 2. 3. 4. 5. ....
如果我在 solve1
函数中使用 C.A=paramvalues[idx]
。
所以问题是如何使用包含我要更新的变量名称的字符串在 njit
函数中更新 C
的属性 A
(就我而言 mystring = 'C.A'
)
1) 引用,因为您希望能够通过直接分配给它在这里使用它 (param=...
) python 中不存在。分配给没有点或 [] 修饰符的左值总是重新绑定该名称,无论是否在 numba 中。编辑:澄清一下,如果名称标有 global
(对全局变量)或 nonlocal
(对封闭变量)则不正确,但均不适用于此处。
2) 在 nopython 模式下,numba 需要在编译时知道你要分配给哪个属性(它本质上是计算 c 结构的偏移量),所以我认为你能做到的最好要做的是编译两个版本的函数。