Использование строковой переменной для указания функции, используемой для нового потока | Python3 - PullRequest
0 голосов
/ 15 января 2020

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

import _thread

def ArbitraryFunction():
    #do function

userIn = "ArbitraryFunction"

try:
    _thread.start_new_thread( userIn, ("Thread-1") )
except:
    print("Failed to start thread.")

Каждый раз, когда я запускаю этот код, я получаю сообщение об ошибке, указывающее, что я не указал функцию. Однако имя функции указано, оно просто содержится в переменной.

Что я сделал не так, и что мне нужно сделать, чтобы это исправить? Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

1 голос
/ 15 января 2020
import _thread
import sys


def ArbitraryFunction():
    # do function

userIn = "ArbitraryFunction"

try:
    _thread.start_new_thread(getattr(sys.modules[__name__], userIn), ("Thread-1",))
except Exception as e:
    print("Failed to start thread due to:\n{}".format(e))

Примечание

Второй аргумент _thread.start_new_thread() должен быть кортежем. Чтобы определить кортеж с одной записью, используйте запятую ("Thread-1",)

1 голос
/ 15 января 2020

Это действительно плохая вещь, потому что выполнение неавторизованного кода - огромный недостаток безопасности.

Это возможно при использовании eval:

def myFunction():
    return 5

eval('myFunction')()

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

Лучший способ сделать это - отобразить функции в словаре, а затем найти функцию по названию. Поскольку функции являются объектами первого класса в Python, вы можете использовать их в большинстве структур данных, например.

# Create a dict of function names and functions
functions = {'myFunction': myFunction, 'squareroot': sqrt}

# Execute one of the functions
return functions['myFunction']()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...