Как передать аргументы функции, которая сама передается как kwarg

#python #function #keyword-argument

#python #функция #ключевое слово-аргумент

Вопрос:

В следующем примере я пытаюсь передать аргументы функции, которая сама была передана как kwarg. Мне не удалось передать аргументы функции ‘func’ из класса ‘TestClass’ в следующем примере:

 import sys, threading; from threading import Thread

def func(kwargs): 
    print('IN:', sys._getframe(0).f_code.co_name)
    for key, value in kwargs.items() :
        print ('KEY:', key, ', VAL:', value, sep='')

class TestClass(Thread):
    
    def __init__(self, name = sys._getframe(0).f_code.co_name, kwargs = None):
        Thread.__init__(self)
        self.name = name
        self.kwargs = kwargs
        print('IN:', self.name)
        
    def run(self):
        func = self.kwargs['func']        
        func_kwargs_inner = {'arg_1': 'INNER-1', 'arg_2': 'INNER-2'}        
        func()  # how to pass func_kwargs_inner to func?
        
def main():
    func_kwargs = {'arg_1': 'OUTER-1', 'arg_2': 'OUTER-2'}  # these get passed
#     func_kwargs = {}  # func_kwargs never gets populated
    kwargs = {'func': (lambda: func(func_kwargs))}    
    test = TestClass(name='my-test', kwargs=kwargs)
    test.start()
    print('PROGRAM END')
    
if __name__ == '__main__':
    main()
  

Если я попытаюсь передать ‘func_kwargs_inner’ в ‘func()’, я получу синтаксические ошибки; если я оставлю список аргументов пустым — как в примере — результат будет:

 IN: my-test
IN: func
KEY:arg_1, VAL:OUTER-1
KEY:arg_2, VAL:OUTER-2
PROGRAM END
  

в то время как требуемый результат, как только я найду способ правильно передать аргументы, будет:

 IN: my-test
IN: func
KEY:arg_1, VAL:INNER-1
KEY:arg_2, VAL:INNER-2
PROGRAM END
  

Как мне передать ‘func_kwargs_inner’ в ‘func()’?

Ответ №1:

Кажется, что если вы сделаете очевидную вещь, то это сработает, и что ваш код в настоящее время явно избегает передачи нужных вам аргументов. В частности, в вашем TestClass.run вы не передаете никаких аргументов func , а вместо этого полагаетесь на аргументы функции, которые жестко закодированы в лямбда-выражении. Так что измените свою строку:

         func()  # how to pass func_kwargs_inner to func?
  

для передачи аргументов:

         func(func_kwargs_inner)
  

Затем в main вместо этого lambda выражения:

     kwargs = {'func': (lambda: func(func_kwargs))}    
  

просто передайте сам объект функции:

     kwargs = {'func': func}    
  

Затем вы получаете ожидаемый результат:

 IN: my-test
IN: func
PROGRAM END
KEY:arg_1, VAL:INNER-1
KEY:arg_2, VAL:INNER-2
  

Комментарии:

1. Спасибо! Я использовал лямбда-выражение, чтобы предотвратить немедленное выполнение ‘func’ в тех случаях, когда мне нужно передать переменное количество функций с переменным количеством аргументов В класс. В данном конкретном случае это не обязательно, и теперь я вижу, что ваше более простое решение — это все, что нужно.