基础教程:
https://www.runoob.com/w3cnote/python-func-decorators.html
修饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。
修饰器让你在一个函数的前后去执行代码
修饰器模型
def a_new_decorator(a_func): # 装饰器
def wrapTheFunction():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return wrapTheFunction
def a_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell")
a_function_requiring_decoration() # 不带装饰器的函数
#outputs: "I am the function which needs some decoration to remove my foul smell"
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
# 带装饰器的函数,把原函数作为参数,经过装饰器返回函数,并赋值到原函数
#now a_function_requiring_decoration is wrapped by wrapTheFunction()
a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()
向decorator传入参数
decorator必须仅接受一个被修饰的函数为参数,这也是为什么我们必须再外包裹一层从而接受那些额外的参数并且产生我们的decorator的原因。这个例子中tags函数是我们的decorator generator
def tags(tag_name): # tag_name是修饰器参数,不属于函数
def tags_decorator(func): # func是被修饰的函数
def func_wrapper(name): # name是被修饰函数的参数
return "<{0}>{1}</{0}>".format(tag_name, func(name))
return func_wrapper
return tags_decorator
@tags("p")
def get_text(name):
return "Hello "+name
print get_text("John")
# Outputs <p>Hello John</p>
目标:用装饰器写多次尝试连接
案例,带修饰器参数的修饰器
from functools import wraps # 装饰器保护
import json
import sys
import pandas as pd
def signal_init(candles_need_num=0): # 默认一根K线都不需要
# # 策略函数修饰器
# # 可以传递2个参数,尝试次数和错误提示
# # 向decorator传入参数,修饰器的参数
# # 带参数的修饰器,引用的时候必须写(),否则被修饰函数是作为第一个参数传过去
# # print(max_try_amount,error_message)
def decorator_func(f): # decorator必须仅接受一个被修饰的函数为参数,不能传递函数的参数
# print(f.__name__)
@wraps(f) # 保护f的__name__不被修改
def wrapped_function(*args, **kwargs): # 被修饰的函数,参数不定
# 测试参数写入df,用于标记输出(爆仓出现在哪个参数下)
# para改成list格式
if len(args): # 传值参数改为关键字参数
kwargs['df'] = args[0]
kwargs['para'] = args[1]
args = () # args清空,只处理kwargs
if len(kwargs): # 对para处理
if isinstance (kwargs['para'], str):
kwargs['df']['para'] = kwargs['para']
kwargs['para'] = json.loads(para)
elif isinstance (kwargs['para'], list):
kwargs['df']['para'] = str(kwargs['para'])
if len(kwargs['df']) < candles_need_num: # K线数量不足情况处理
temp_df = f(*args, **kwargs)
temp_df['signal'] = 0
return temp_df
else:
return f(*args, **kwargs) # 传回函数计算值
return wrapped_function # 返回装饰函数(函数本身)
return decorator_func
@signal_init(candles_need_num=0) # 修饰器不带参数(定义时直接写(f)),引用时不能带()
def siganls(df=pd.DataFrame(columns=['A', 'B', 'C'], index=[0,1,2]), para=[1,1]):
print(df)
print('para:', type(para))
return df
if __name__ == '__main__':
df = pd.DataFrame(columns=['A', 'B', 'C'], index=[0,1,2])
para =str([2, 2])
# para = json.loads(para)
# tup = (df, para)
# tup =(1,1)
# print(tup)
# print(para)
# exit()
print(siganls(df, para))
# print(siganls(df=df, para=para)) #