У меня есть довольно обширный инструмент моделирования, написанный на python
, который требует от пользователя вызова функций для настройки среды в строгом порядке, поскольку np.ndarrays
сначала создаются (и изменяются путем добавления и т. Д.) и после этого определяются представления памяти конкретных ячеек этих массивов.
В настоящее время для каждой части среды требуется около 4 различных вызовов функций, с простыми >> 100
частями.
Таким образом, мне нужно объединить вызовы функций каждой части путем синтаксического (не основанного на таймерах) отсрочки выполнения некоторых функций до тех пор, пока не будут выполнены все предыдущие функции, при этом сохраняя строгий порядок, позволяющий использовать представления памяти .
Кроме того, все функции, вызываемые пользователем, используют PEP 3102 аргументы в стиле только для ключевых слов, чтобы уменьшить вероятность ошибок ввода и все они методы экземпляра с self
в качестве первого параметра, с self
, содержащим ссылки на массивы для построения представлений памяти.
Моя текущая реализация использует list
s для хранения функций и dict
для аргументов ключевых слов каждой функции. Это показано здесь, опуская параметры класса и self, чтобы сделать его коротким:
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)
Какой самый лучший (самый питонический) метод для этого? Есть ли недостатки?
И самое главное: мои ссылки на np.ndarrays
, переданные функциям в self
, все еще будут ссылками, так что адреса памяти этих массивов будут по-прежнему правильными при выполнении функций, , если адреса памяти изменить между сохранить вызовы функций в списке (или оформить их) и выполнить их?
Скорость выполнения здесь не имеет значения.