Давайте посмотрим, что сначала делают декораторы.Декоратор принимает объект (это может быть функция, класс или, возможно, что-то еще), что-то делает и возвращает замещающий объект, который переназначается на имя оригинала.
В этом контексте register_function
ничего полезного не делает.Возвращает оболочку, которая вызывает неизмененный оригинал.Основываясь на названии, вы, вероятно, захотите записать функцию в некотором реестре, например в словаре:
function_registry = {}
def register_command(func):
function_registry[func.__name__] = func
return func
Помните, что вещи, которые декоратор не должен затрагивать функцию напрямую (илисовсем).И нет ничего плохого в простом возврате функции ввода.
Теперь давайте рассмотрим использование только что созданного реестра.Ваш текущий execute_command
ничего не выполняет.Он создает и возвращает вызываемый объект, который будет вызывать декорированную функцию, если вы вызываете ее без аргументов.execute_command
на самом деле не вызывает результат.
Возможно, вы захотите, чтобы функция с именем, например execute_command
, искала команду по имени и запустила ее:
def execute_command(name, *args, **kwargs)):
return function_registry[name](*args, **kwargs)
Так что теперь вы можете сделать что-то вроде
@register_command
def some_math_function(variable):
return variable + 1
, что оставит функцию неизменной, но добавит запись в реестр, которая сопоставляет имя 'some_math_function'
с объектом функции some_math_function
.
* 1025.* Ваша программа становится
func_name = input('what function do you want to run? ') # enter some_math_func
input_var = int(input("input your variable: "))
response = execute_command(func_name, input_var)
print(response())
Этот пример не выполняет никакой проверки типов, отслеживает количество аргументов или иным образом позволяет вам проявить творческий подход к вызову функций, но он поможет вам начать работу с декораторами.
Итак, это элементарная система для преобразования фиксированного числа входов в требуемые типы.Аргументы конвертируются в указанном порядке.Функция отвечает за выдачу ошибки, если вы не указали достаточно входных данных.Ключевые слова не поддерживаются:
function_registry = {}
def register_function(*converters):
def decorator(func):
def wrapper(*args):
real_args = (c(arg) for c, arg in zip(converters, args))
return func(*real_args)
function_registry[func.__name__] = wrapper
return wrapper
return decorator
@registrer_function(int)
def some_math_func(variable):
return variable + 1
def execute_command(name, *args):
return function_registry[name](*args)
command = input("command me: ") # some_math_func 1
name, *args = command.split()
result = execute_command(name, *args)
print(result)