Как обновить переменную jitclass с ее строковым именем, передав функцию setter самому jitclass? - PullRequest
1 голос
/ 13 марта 2020

Я ищу способ изменить переменную jitclass с ее именем в виде строки. Я попытался написать функцию установки и получения (get_A и set_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 jitclass, int32, float64

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)

1 Ответ

0 голосов
/ 20 марта 2020

Вот решение, которое я придумал. Сначала я написал функцию, которая возвращает список имен переменных, которые я могу обновить

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

, затем в jitclass я написал функцию, которая может обновлять переменную в соответствии с индексом на основе порядка * 1004. *.

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_val jitclass.

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

вот весь код.

из numba import 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')
...