我有一个用python
编写的相当广泛的模拟工具,它要求用户调用函数以严格的顺序设置环境,因为np.ndarrays
最初是创建的(并且由附加等)然后定义对这些阵列的特定单元的存储器视图
目前,环境的每个部分都需要设置大约4个不同的函数调用,并且容易>> 100
个部分
因此,我需要通过语法(不基于计时器)将每个部分的函数调用结合起来,推迟执行某些函数,直到所有前面的函数都被执行,同时仍保持严格的顺序以便能够使用内存视图。
此外,用户调用的所有函数都使用PEP 3102样式的仅关键字参数来减少输入错误的概率和所有实例方法使用self
作为第一个参数,self
包含对数组的引用以构造内存视图。
我当前的实现是使用list
来存储函数,并使用dict
来为每个函数的keyworded参数。这里显示了这一点,省略了类和自身参数,使其变短:
def fun1(*, x, y): # easy minimal example function 1
print(x * y)
def fun2(*, x, y, z): # easy minimal example function 2
print((x + y) / z)
fun_list = [] # list to store the functions and kwargs
fun_list.append([fun1, {'x': 3.4, 'y': 7.0}]) # add functions and kwargs
fun_list.append([fun2, {'x':1., 'y':12.8, 'z': np.pi}])
fun_list.append([fun2, {'x':0.3, 'y':2.4, 'z': 1.}])
for fun in fun_list:
fun[0](**fun[1])
我想要实现的是使用decorator
通过添加generator
推迟函数执行,以便能够在调用函数时将所有参数传递给函数,但不执行他们,如下图所示:
def postpone(myfun): # define generator decorator
def inner_fun(*args, **kwargs):
yield myfun(*args, **kwargs)
return inner_fun
fun_list_dec = [] # list to store the decorated functions
fun_list_dec.append(postpone(fun1)(x=3.4, y=7.0)) # add decorated functions
fun_list_dec.append(postpone(fun2)(x=1., y=12.8, z=np.pi))
fun_list_dec.append(postpone(fun2)(x=0.3, y=2.4, z=1.))
for fun in fun_list_dec: # execute functions
next(fun)
哪种方法最好(最pythonic)?有什么缺点吗?
最重要的是:np.ndarrays
对self
内部函数的引用是否仍然是引用,这样在执行函数时这些数组的内存地址仍然正确, if 内存地址在之间更改将函数调用保存到列表(或正在修饰)并执行它们?
执行速度无关紧要。
答案 0 :(得分:3)
答案 1 :(得分:0)
由于评论代码太复杂而且基于juanpa.arrivillaga的答案,我将添加一篇完整的帖子,简短解释我的意思是更新对数组的引用:
def fun1(*, x, y): # easy minimal example function 1
print(x * y)
arr = np.random.rand(5)
f1_lam = lambda:fun1(x=arr, y=5.)
f1_par = partial(fun1, x=arr, y=5.)
f1_lam() # Out[01]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 ]
f1_par() # Out[02]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 ]
# manipulate array so that the memory address changes and
# passing as reference is "complicated":
arr = np.append(arr, np.ones((2,1)))
f1_lam() # Out[03]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 5. 5.]
f1_par() # Out[02]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 ]
lambda
的行为正是我在这个问题中寻找的行为。
dict
和decorator
的示例不起作用,functools.partial
也不行。知道为什么lambda
有效吗?只是出于兴趣:有没有办法更新dict
中对数组的引用,以便它也可以这样工作?