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

时间:2017-12-04 02:40:21

标签: python decorator

我正在学习使用python decorator。

    library(mlbench)
   library(h2o)

data(Sonar)
dfh2o = as.h2o(Sonar)
splits=h2o.splitFrame(dfh2o)

train = splits[[1]]
valid = splits[[2]]

gbm_no_val_frame <- h2o.gbm(x = colnames(df), y = "Class", training_frame = train,
                         nfolds = 5, seed = 1234, ntrees  = 4000, stopping_rounds = 5)


gbm_val_frame <- h2o.gbm(x = colnames(df), y = "Class", training_frame = train, validation_frame = valid,
                    nfolds = 5, seed = 1234, ntrees  = 4000, stopping_rounds = 5)            

   h2o.flow()  ### to see the validation frame stopping under models.

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

e.g。我正在尝试用python做一个玩具远程程序调用(RPC)。

def my_dcrtr(fun):
    def new_fun():
        return fun()
    return new_fun

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

1 个答案:

答案 0 :(得分: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))

输出:

60
{'a': 10, 'b': 20, 'c': 30}

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

编辑:my_funct正文中的代码在包装函数(decorated_fun)中调用时执行,因为在args范围内声明的decorated_fun传递给local_args并在yourNavigationView.setItemIconTintList(null); 解压缩。