#python #function #dynamic
#python #функция #динамический
Вопрос:
Я динамически добавляю функции в class ( A
) с некоторыми переменными ( my_name
). Но когда я вызываю функции в class ( A
), я получаю правильную функцию (правильное имя функции), но с переменными из последней функции. Как динамически устанавливать переменные в функции или как решить подобную проблему?
class A:
pass
function_name_list = ['first/function', 'second/function', 'third/function']
def add_method(cls, fnctname):
def decorator(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
return func(*args, **kwargs)
setattr(cls, fnctname, wrapper)
return func
return decorator
def create_functions():
for x in function_name_list:
name = x.replace('/', '')
@add_method(A, name)
def foo(value):
my_name = copy.deepcopy(name)
with open('./file' str(my_name) '.txt', 'a') as f:
f.write(str(time.time()) ',' my_name ',' str(value) "n")
print('Call: ', my_name)
a = A()
create_functions()
for x in function_name_list:
name = x.replace('/', '')
getattr(a, '%s' % name)(1)
Ответ №1:
Внутри вашего create_function
, def foo()
привязывается к переменной name
. Он получит текущее значение name
при вызове функции. Существует только одна name
переменная, поэтому все ваши foo
функции привязаны к одной и той же переменной.
Если вы действительно хотите это сделать, вы должны убедиться, что для каждой функции привязана отдельная переменная. Выделите все тело вашего for
цикла в отдельную функцию, после чего она создаст разные переменные для каждой функции.
def create_functions():
for x in function_name_list:
create_foo(x.replace('/', ''))
def create_foo(name):
@add_method(A, name)
def foo(value):
with open('./file' str(name) '.txt', 'a') as f:
f.write(str(time.time()) ',' name ',' str(value) "n")
print('Call: ', name)
( copy.deepcopy()
на a str
вернет оригинал str
, поэтому я его удалил.)
Гораздо более простой метод — просто связать аргументы с помощью functools.partial
:
import functools
def foo(self, value, name):
with open('./file' str(name) '.txt', 'a') as f:
f.write(str(time.time()) ',' name ',' str(value) "n")
print('Call: ', name)
def create_functions():
for x in function_name_list:
name = x.replace('/', ''))
setattr(A, name, functools.partial(foo, name=name))