版权声明: https://blog.csdn.net/dashoumeixi/article/details/83758514
lru_cache : 缓冲装饰器, 实际上自己可以用dict 来实现 .
singledispatch : 相当于 c++ 中 stl 的函数特化(具体实例化) .
如果有兴趣学c++ stl ,这里是我写的函数模版 : 函数模版 特化 模版指针 以及 类模版 具体化 特化 部分特化 友元
一个例子说明 lru_cache:
#一个普通装饰器
def clock(func):
@functools.wraps(func) #把原函数的__doc__ 以及 __name__ 复制进来
def clocked(*args, **kwargs):
'''clocked'''
start = time.perf_counter()
res = func(*args, **kwargs)
elapsed = time.perf_counter() - start
name = func.__name__
arg_str = ','.join(repr(arg) for arg in args)
print("elapsed [%0.8fs] %s(%s) %s: " % (elapsed , name,arg_str,res))
return res
return clocked
#maxsize 存储多少条记录 , typed 把不同的类型区分
@functools.lru_cache(maxsize=128,typed=True) #可以把这行注释掉看看
@clock #装饰一下
def fibo(n):
if n < 2:
return n
return fibo(n-2) + fibo(n-1)
if __name__ == "__main__":
fibo(8)
#输出: 用了functools.lru_cache 后
elapsed [0.00000064s] fibo(0) 0:
elapsed [0.00000064s] fibo(1) 1:
elapsed [0.00005322s] fibo(2) 1:
elapsed [0.00000096s] fibo(3) 2:
elapsed [0.00007662s] fibo(4) 3:
elapsed [0.00000096s] fibo(5) 5:
elapsed [0.00009906s] fibo(6) 8:
elapsed [0.00000096s] fibo(7) 13:
elapsed [0.00012182s] fibo(8) 21:
singledispatch : 根据类型来调用某个函数实现 .
简单来说 c++ 的模版是一种通用类型, 跟某个具体类型( int , str ....) 没关系.
一个c++的例子 :
如果没学过stl的话, 请无视这些奇怪的东西, 只需要你专注 T 就行了.
T 代表某一种数据类型, 比方说 int , double ......
template <typename T>
T compare(const T & a, const T & b)
{
if(a >=b)
return a;
return b;
}
强调一下, 请无视这些 const(只读) 啊, &(引用) 这类符号 . python 都是引用.
现在比方说 你调用了 compare( 1, 2)
此时编译器根据参数类型 int 将给你生成一个函数 int compare(const int&,const int&)
如果 : compare( 1.0 , 2.0 ) 生成 double compare(const double&,const double&)
请注意.函数内部都不会改变
那么现在问题来了, 如果要进行字符串比较, 就不能使用这样的方式了把.
有一个东西叫特化(具体实例化):
//字符串比较 , 再次请无视这些参数,我知道很丑,很难看懂.总之这是一个字符串比较的特化版本
template <> // <> 意味着特化
const char * compare(const char * const &a, const char * const & b)
{
return strcmp(a,b);
}
现在当你使用
const char * p1 = "123";
const char * p2 = "456";
compare(p1,p2); // 调用 compare(const char* const &,const char* const &);
#比方说有那么一个函数 . 需要根据类型来输出具体的情况,那么下面是一种实现
#这种方式比较方便,但难以维护 . 有可能上百个情况
def print_type(obj):
if isinstance(obj,int): #每次都用 isinstance 来判断
print("int")
elif isinstance(obj,str):
print("str")
else:
print("other")
#下面是singledispatch
#特殊处理的函数名 我这里都是 _ , 请随意吧
#总的来说就是 根据不同的类型来调用不同的函数
@functools.singledispatch #装饰之后,这个相当于一个模版了
def print_type2(obj):
print("原始版本 type:%s" %type(obj))
@print_type2.register(str) #特殊处理 str ,如果 obj 是str 将调用这个函数, 相当于c++的特化
def _(text):
print("im str : %s , text:%s" % (type(text),text))
@print_type2.register(int) #处理 int的版本, 如果obj 是 int 调用此函数
def _(n):
print("im int: %s , n:%s" % (type(n), n))
if __name__ == "__main__":
print_type2(1) #将调用_(n)