我不知道该怎么做,坦率地说,我不知道这是否可能。
我想编写一个修饰器来改变函数的调用方式。用示例代码最容易看到:
def my_print(*args, **kwargs):
print(args[0].upper())
@reroute_decorator('print', my_print)
def my_func():
print('normally this print function is just a print function...')
print('but since my_func is decorated with a special reroute_decorator...')
print('it is replaced with a different function, and its args sent there.')
my_func()
# NORMALLY THIS PRINT FUNCTION IS JUST A PRINT FUNCTION...
# BUT SINCE MY_FUNC IS DECORATED WITH A SPECIAL REROUTE_DECORATOR...
# IT IS REPLACED WITH A DIFFERENT FUNCTION, AND ITS ARGS SENT THERE.在python中,具有这种功能的装饰师可能吗?
现在,如果它太复杂的话,我真的不需要它,我只是想不出如何用简单的方法来完成它。
这种问题是微不足道的吗?还是真的很复杂?
发布于 2019-10-28 20:34:29
要详细说明@Dan D.'s answer,您需要创建一个新的函数对象来替换原始函数,如下所示:
from types import FunctionType
def reroute_decorator(**kwargs):
def actual_decorator(func):
globals = func.__globals__.copy()
globals.update(kwargs)
new_func = FunctionType(
func.__code__, globals, name=func.__name__,
argdefs=func.__defaults__, closure=func.__closure__)
new_func.__dict__.update(func.__dict__)
return new_func
return actual_decorator这里唯一的问题是,更新后的函数对象是唯一能够看到传入的任何kwargs的对象,因为它们将被欺骗为全局对象。此外,在调用装饰器函数之后对模块所做的任何修改对修饰函数都是不可见的,但这不应该是一个问题。您可以进行更深一层的操作,并创建一个代理字典,该字典允许您正常地与原始密钥交互,除了您显式定义的键(如print )之外,但这超出了这里的范围。
我已经更新了您的print实现,使其更加通用,并使对装饰器函数的输入更加pythonic (少了MATLABy):
def my_print(*args, **kwargs):
print(*(str(x).upper() for x in args), **kwargs)
@reroute_decorator(print=my_print)
def my_func():
print('normally this print function is just a print function...')
print('but since my_func is decorated with a special reroute_decorator...')
print('it is replaced with a different function, and its args sent there.')其结果是:
>>> my_func()
NORMALLY THIS PRINT FUNCTION IS JUST A PRINT FUNCTION...
BUT SINCE MY_FUNC IS DECORATED WITH A SPECIAL REROUTE_DECORATOR...
IT IS REPLACED WITH A DIFFERENT FUNCTION, AND ITS ARGS SENT THERE.发布于 2019-10-28 20:34:44
您可以使用更新的globals字典创建一个新函数,以便将全局函数绑定到所需的值。
注意,这比实际的动态范围要弱,因为函数调用的任何函数都将看到原始绑定,而不是修改后的绑定。
参见在namespaced_function中引用的How does Python's types.FunctionType create dynamic Functions?
https://stackoverflow.com/questions/58597680
复制相似问题