首页 > 解决方案 > 如何通过将 setter 函数传递给 jitclass 本身来使用其字符串名称更新 jitclass 变量?

问题描述

我正在寻找一种方法来修改jitclass名称为字符串的变量。我试图编写一个 setter 和 getter 函数(get_Aset_A),我得到了jitclass. 然后我想将该方法传递给一个jitclass方法来更新变量的值。但是我得到并且错误地说:

numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
non-precise type pyobject
[1] During: typing of argument at <string> (3)

File "<string>", line 3:
<source missing, REPL/exec in use?>

This error may have been caused by the following argument(s):
- argument 1: cannot determine Numba type of <class 'tuple'>

这里是最小的例子:

from numba import float64
from numba.experimental import jitclass

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

@jitclass(spec)
class maClass:
    def __init__(self):
        self.A = 0

    def get_A(self):
        return self.A

    def set_A(self, x):
        self.A = x

    def update(self, func, val):
        func(val)

C1 = maClass()
print('A', C1.A)

Names= ['A']
vals= [1.]

func = getattr(C1, 'set_' + Names[0])
print(func)

C1.update(func, vals[0])
print('A', C1.A)

标签: pythonnumba

解决方案


这是我想出的解决方案。我首先编写了一个函数,它返回我可以更新的变量名列表

def get_Variable_Names():
    return ['A','B','C']

然后,在 jitclass 中,我编写了一个函数,该函数可以根据get_Variable_Names.

def update_val(self, i, var):
    if i == 0:
        self.A = var
    elif i == 1:
        self.B = var
    elif i == 2:
        self.C = var

为了使用这个函数,我在返回的列表中搜索变量名的索引,get_Variable_Names然后调用update_valjitclass 的函数。

listnames = get_Variable_Names()
val = 1.
name = 'A'
index = listnames.index(name)
C1.update_val(index,val)

这是所有的代码。

从 numba 导入 jitclass,int32,float64

def get_Variable_Names():
    return ['A','B','C']

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

@jitclass(spec)
class maClass():
    def __init__(self,):
        self.A = 0.
        self.B = 0.
        self.C = 0.

    def update_val(self, i, var):
        if i == 0:
            self.A = var
        elif i == 1:
            self.B = var
        elif i == 2:
            self.C = var

C1 = maClass()
listnames = get_Variable_Names()
val = 1.
name = 'A'
index = listnames.index(name)
C1.update_val(index,val)

val = 2.
name = 'B'
index = listnames.index(name)
C1.update_val(index,val)

val = 3.
name = 'C'
index = listnames.index(name)
C1.update_val(index,val)
print('A',C1.A)
print('B',C1.B)
print('C',C1.C)

这不是我一直在寻找的,而是现在找到的。

我还在等待更好的东西。

我什至写了一个脚本来编写 if else update_val 函数,因为当我们有大量变量要修改时,它可能会很乏味

listnames= ['A','B','C']

for i, n in enumerate(listnames):
    if i == 0:
        print('if i == ' + str(i)+ ' :\n\tself.' + n + ' = var')
    else:
        print('elif i == ' + str(i) + ' :\n\tself.' + n + ' = var')

推荐阅读