Python:使用装饰器修改函数的内部行为

Shi*_*Zhu 6 python decorator

我正在学习使用python装饰器.

def my_dcrtr(fun):
    def new_fun():
        return fun()
    return new_fun
Run Code Online (Sandbox Code Playgroud)

我意识到装饰功能'fun'就像装饰器里面的黑盒子一样.我可以选择在new_fun中使用fun()或者根本不使用fun().但是,我不知道我是否可以闯入'有趣'并与new_fun中的fun的本地范围进行交互?

例如,我正在尝试使用python制作玩具远程程序调用(RPC).

def return_locals_rpc_decorator(fun):
    def decorated_fun(*args, **kw):
        local_args = fun(*args, **kw)
        # pickle the local_args and send it to server
        # server unpickle and doing the RPC
        # fetch back server results and unpickle to results
        return rpc_results

    return decorated_fun


@return_locals_rpc_decorator
def rpc_fun(a, b, c=3):
    return locals() # This looks weird. how can I make this part of the decorator?


print(rpc_fun(2, 1, 6))
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我尝试使用'locals()'命令在运行时获取rpc_fun的参数列表.然后将其发送到服务器执行.而不是让rpc_fun返回其locals(),是否可以使用装饰器来检索修饰函数的参数空间?

Aja*_*234 3

您可以使用Python3的函数注释:

def return_locals_rpc_decorator(fun):
   def decorated_fun(*args, **kw):
      local_args = fun(*args, **kw) 
      print(local_args)
      fun_parameters = fun.__annotations__
      final_parameters = {a:list(args)[int(b[-1])-1] for a, b in fun_parameters.items() if a != 'return'}
      return final_parameters
   return decorated_fun

@return_locals_rpc_decorator
def my_funct(a:"val1", b:"val2", c:"val3") -> int:
    return a + b + c

print(my_funct(10, 20, 30))
Run Code Online (Sandbox Code Playgroud)

输出:

60
{'a': 10, 'b': 20, 'c': 30}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以使用包装函数decorated_fun来访问修饰函数的参数以及注释指定的更多信息。我更改了注释中的参数描述,以便每个字符串值都以可用于索引的数字结尾args。但是,如果您不想更改注释中的参数说明,可以按结束符排序。

编辑: 主体中的代码my_funct在包装函数 ( decorated_fun) 中调用时执行,因为args在 范围内声明的 ,decorated_fun被传递到并在 中解包local_args