如何通过将 setter 函数传递给 jitclass 本身来更新带有字符串名称的 jitclass 变量?
How to update a jitclass variable with its string name by passing a setter function to the jitclass itself?
我正在寻找一种方法来修改 jitclass
变量并将其名称作为字符串。我试着写了一个setter和getter函数(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 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)
这是我想出的解决方案。
我首先写了一个函数 return 我可以更新的变量名列表
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
编辑的列表return中搜索一个变量名的索引,然后调用jitclass的update_val
函数。
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')
通过几个小改动,您实际上可以在 numba 中使用函数指针。基于大量实验,我想出了以下内容,first item on the FAQ.
首先要注意的是 getattr(C1, 'set_A')
returns 一个 Python 方法对象。在撰写本文时 (v0.53.1),这不是 numba 直接支持的内容。相反,您必须获得指向实际 jit
ted 函数的指针,这可以通过相对未记录的 _numba_type_
属性来实现。这包含一堆非常有用的对象的方法和属性的描述符。具体来说,您的 func
对象由
给出
func = C1._numba_type_.jit_methods['set_A']
要注意的第二件事是编译函数 func
需要一个明确的 self
参数,它是 maClass.class_type.instance_type
的子类型。仅使用一个参数调用它会导致 update
:
中的编译错误
func(self, val)
这是完整的示例(包括固定的 jitclass
导入):
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 = self.B = self.C = 0
def get_A(self):
return self.A
def set_A(self, x):
self.A = x
def update(self, func, val):
func(self, val)
C1 = maClass()
print('A', C1.A)
Names = ['A']
vals = [1.]
func = C1._numba_type_.jit_methods['set_' + Names[0]]
print(func)
C1.update(func, float64(vals[0]))
print('A', C1.A)
我正在寻找一种方法来修改 jitclass
变量并将其名称作为字符串。我试着写了一个setter和getter函数(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 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)
这是我想出的解决方案。 我首先写了一个函数 return 我可以更新的变量名列表
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
编辑的列表return中搜索一个变量名的索引,然后调用jitclass的update_val
函数。
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')
通过几个小改动,您实际上可以在 numba 中使用函数指针。基于大量实验,我想出了以下内容,first item on the FAQ.
首先要注意的是 getattr(C1, 'set_A')
returns 一个 Python 方法对象。在撰写本文时 (v0.53.1),这不是 numba 直接支持的内容。相反,您必须获得指向实际 jit
ted 函数的指针,这可以通过相对未记录的 _numba_type_
属性来实现。这包含一堆非常有用的对象的方法和属性的描述符。具体来说,您的 func
对象由
func = C1._numba_type_.jit_methods['set_A']
要注意的第二件事是编译函数 func
需要一个明确的 self
参数,它是 maClass.class_type.instance_type
的子类型。仅使用一个参数调用它会导致 update
:
func(self, val)
这是完整的示例(包括固定的 jitclass
导入):
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 = self.B = self.C = 0
def get_A(self):
return self.A
def set_A(self, x):
self.A = x
def update(self, func, val):
func(self, val)
C1 = maClass()
print('A', C1.A)
Names = ['A']
vals = [1.]
func = C1._numba_type_.jit_methods['set_' + Names[0]]
print(func)
C1.update(func, float64(vals[0]))
print('A', C1.A)