Как написать функцию, которая принимает в качестве входных данных другую функцию и ее аргументы, запускает ее в потоке и уничтожает поток после выполнения? - PullRequest
4 голосов
/ 01 июля 2019

Я пытаюсь написать функцию в микропифоне, которая берет имя другой функции вместе с аргументами и аргументами ключевых слов, создает поток для запуска этой функции и автоматически выходит из потока после ее возврата.

Требование заключается в том, что функции, которые должны выполняться в этом потоке, могут вообще не иметь аргументов / аргументов ключевых слов или могут иметь их в переменных числах.

До сих пор я пытался:

import _thread

def run_main_software():
    while True:
        pass


def run_function(function, arguments, kwarguments):
    def run_function_thread(function, args, kwargs):
        function(*args, **kwargs)
        _thread.exit()

    _thread.start_new_thread(run_function_thread, (function, arguments, kwarguments))


_thread.start_new_thread(run_main_software, ())


def test_func(thingtoprint):
    print(thingtoprint)

Однако, когда я пытаюсь запустить это, я получаю:

>>> run_function(test_func, "thingtoprint")
>>> Unhandled exception in thread started by <function run_function_thread at 0x2000fb20>
Traceback (most recent call last):
  File "<stdin>", line 44, in run_function_thread
AttributeError: 'NoneType' object has no attribute 'keys'

Если я передаю все три аргумента:

>>> run_function(test_func, "Print this!", None)
>>> Unhandled exception in thread started by <function run_function_thread at 0x20004cf0>
Traceback (most recent call last):
  File "<stdin>", line 48, in run_function_thread
TypeError: function takes 1 positional arguments but 11 were given

Что я здесь не так делаю?

Спасибо!

РЕДАКТИРОВАТЬ: Я пытался работать с («Распечатать это!») По предложению Джакомо Альзетта, и я получаю это:

>>> run_function(test_func, ("Print this!", ), None)
>>> Unhandled exception in thread started by <function run_function_thread at 0x20003d80>
Traceback (most recent call last):
  File "<stdin>", line 44, in run_function_thread
AttributeError: 'NoneType' object has no attribute 'keys'

РЕДАКТИРОВАТЬ2: Это работает, если я делаю это:

>>> run_function(test_func, ("Print this!", ), {})
>>> Print this!

1 Ответ

1 голос
/ 03 июля 2019

Проблема заключалась в том, что в первом случае мне не хватало необязательного аргумента (kwarguments). Поэтому ** kwargs не может найти ключи для перебора, что приводит к ошибке:

AttributeError: 'NoneType' object has no attribute 'keys'

Во втором случае я явно передал None ** kwargs вместо словаря. Здесь, однако, он замечает, что я передал строку * args, а не кортежу. Таким образом, * args по существу перебирает строку и принимает каждый символ в строке как отдельный аргумент. В результате:

TypeError: function takes 1 positional arguments but 11 were given

В третьем случае я передал кортеж * args, но ошибка по сути та же, что и в первом случае.

Решение состоит в том, чтобы передать кортеж * args и пустой словарь ** kwargs, вот так:

>>> run_function(test_func, ("Print this!", ), {})
>>> Print this!
...