Return 一个带有包装器的函数对象
Return a function object with wrapper
我有一个复杂的库,用户可以向其中添加函数。然后在接受输入的程序中使用该库。问题是,函数没有按照我希望的方式处理。让我来说明一下(我已经简化了代码来说明要点):
import functools
def register_command(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
def execute_command(func, *args, **kwargs)):
return functools.partial(func, *args, **kwargs))
'''DECORATORS: EASY WAY FOR THE USER TO ADD NEW FUNCTIONS TO THE LIBRARY'''
@register_command
def some_math_function(variable):
return variable + 1
'''THIS IS THE PROGRAM WHICH USES THE ABOVE LIBRARY & USER-CREATED FUNCTIONS'''
input_var = input("input your variable: ")
response = execute_command(register_command, input_var)
print(response())
因此,如果用户输入“10”,input_var = 10
,我希望算法为 return 11。相反,我得到的是:
<function register_command.<locals>.wrapper at 0x110368ea0>
我哪里错了?
我们先看看装饰器是做什么的。装饰器接受一个对象(可以是一个函数,class,或者可能是其他东西),做一些事情,然后 returns 一个被重新分配给原始对象名称的替换对象。
在这种情况下,register_function
没有任何用处。它 returns 一个调用未修改原始文件的包装器。根据名称,您可能希望将函数记录在某些注册表中,例如字典:
function_registry = {}
def register_command(func):
function_registry[func.__name__] = func
return func
请记住,装饰器所做的事情不必直接(或根本)影响功能。而且直接返回输入函数也没什么问题
现在让我们来看看如何使用我们刚刚制作的注册表。您当前的 execute_command
不执行任何操作。它创建并 returns 一个可调用对象,如果您不带参数调用它,该对象 将 调用装饰函数。 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
。
你的程序变成了
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)
我有一个复杂的库,用户可以向其中添加函数。然后在接受输入的程序中使用该库。问题是,函数没有按照我希望的方式处理。让我来说明一下(我已经简化了代码来说明要点):
import functools
def register_command(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
def execute_command(func, *args, **kwargs)):
return functools.partial(func, *args, **kwargs))
'''DECORATORS: EASY WAY FOR THE USER TO ADD NEW FUNCTIONS TO THE LIBRARY'''
@register_command
def some_math_function(variable):
return variable + 1
'''THIS IS THE PROGRAM WHICH USES THE ABOVE LIBRARY & USER-CREATED FUNCTIONS'''
input_var = input("input your variable: ")
response = execute_command(register_command, input_var)
print(response())
因此,如果用户输入“10”,input_var = 10
,我希望算法为 return 11。相反,我得到的是:
<function register_command.<locals>.wrapper at 0x110368ea0>
我哪里错了?
我们先看看装饰器是做什么的。装饰器接受一个对象(可以是一个函数,class,或者可能是其他东西),做一些事情,然后 returns 一个被重新分配给原始对象名称的替换对象。
在这种情况下,register_function
没有任何用处。它 returns 一个调用未修改原始文件的包装器。根据名称,您可能希望将函数记录在某些注册表中,例如字典:
function_registry = {}
def register_command(func):
function_registry[func.__name__] = func
return func
请记住,装饰器所做的事情不必直接(或根本)影响功能。而且直接返回输入函数也没什么问题
现在让我们来看看如何使用我们刚刚制作的注册表。您当前的 execute_command
不执行任何操作。它创建并 returns 一个可调用对象,如果您不带参数调用它,该对象 将 调用装饰函数。 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
。
你的程序变成了
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)