#1. 递归函数调用
#递归函数调用
def fibonacci(n):
'''fibonacci function'''
if n<=1:
return 1
return fibonacci(n-1)+fibonacci(n-2)
fibonacci(50)#迭代次数太多导致程序崩盘,长时间没有返回
#2.使用Cache记录已计算结果,如有则直接返回,没有则添加
def fibonacci1(n,cache=None):
if n<=1:
return 1
if cache==None:
cache={}
if n in cache:
return cache[n]
else:
cache[n]=fibonacci1(n-1,cache)+fibonacci1(n-2,cache)
return cache[n]
fibonacci1(100)
#计算速度很快
#计算结果: 573147844013817084101
#3.#创建闭包装饰器
def collect(func):
cache={}
def wrap(*args):
if args not in cache:
cache[args]=func(*args)
return cache[args]
return wrap
@collect
def fibonacci2(n):
if n<=1:
return 1
return fibonacci2(n-1)+fibonacci2(n-2)
fibonacci2(100)# 或使用 fibonacci2=collect(fibonacci2)
#计算结果: 573147844013817084101
#4.#如何跳过Wrap将function的属性显示出来
fibonacci.__doc__ #结果为 'fibonacci function'
fibonacci.__name__ #结果为 'fibonacci'
但是 fibonacci2.__name__ 结果却是 'wrap'
可以使用 functiontools中的装饰器wraps装饰内部 包裹函数,将原函数属性传递到Wrap函数里
#4.1 from functools import wraps
#4.2 用wraps装饰器装饰闭包函数,@wraps(func)
#打印fibonacci2.__name__结果为fibonacci2
#5.#如何判断函数传入的参数类型是否正确
from inspect import signature
def typeassert(*ty_args,**ty_kargs):
def decorator(func):
sig=signature(func)
print(sig)
btypes=sig.bind_partial(*ty_args,**ty_kargs).arguments
#btypes=OrderedDict([('a', <class 'int'>), ('b', <class 'int'>), ('c', <class 'int'>)])
print(btypes)
def wrapper(*args,**kargs):
#print(sig.bind(*args,**kargs).arguments.items())
#sig.bind(*args,**kargs).arguments.items() =odict_items([('a', 1), ('b', 9), ('c', 3)])
for name,obj in sig.bind(*args,**kargs).arguments.items():
if name in btypes:
if not isinstance(obj,btypes[name]):
raise TypeError('{0} must be {1}'.format(name,btypes[name]))
return func(*args,**kargs)
return wrapper
return decorator
@typeassert(int,int,int)#也可以只定义前两个(int,int)
def f(a,b,c):
print('{},{},{}'.format(a,b,c))
f(1,9,3)
#结果1,9,3
f('a1','bb','cc')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-66-61585f180c14> in <module>
21 print('{},{},{}'.format(a,b,c))
22 f(1,9,('a3','b5'))
---> 23 f('a1','bb','cc')
<ipython-input-66-61585f180c14> in wrapper(*args, **kargs)
13 if name in btypes:
14 if not isinstance(obj,btypes[name]):
---> 15 raise TypeError('{0} must be {1}'.format(name,btypes[name]))
16 return func(*args,**kargs)
17 return wrapper
TypeError: a must be <class 'int'>
#6.#如何统计函数运行时间
import time
import logging
def warn(timeout):
timeout=[timeout]
def decorator(func):
def wrapper(*args,**kargs):
start=time.time()
res=func(*args,**kargs)
used=time.time()-start
if used > timeout[0]:
msg='{}: {}>{}'.format(func.__name__,used,timeout[0])
logging.warn(msg)
print(msg)
return res
def setTimeout(k):
#nonlocal timeout
timeout[0]=k
wrapper.setTimeout=setTimeout
return wrapper
return decorator
from random import randint
@warn(1.5)
def test():
print('in test')
while randint(0,1):
time.sleep(0.7)
for _ in range(30):
test()
'''#结果显示 in test in test in test in test
D:\software\Anaconda1\lib\site-packages\ipykernel_launcher.py:13: DeprecationWarning: The 'warn' function is deprecated, use 'warning' instead del sys.path[0] WARNING:root:test: 2.802633285522461>1.5 '''
#此博客为本人学习Python教程文档,并通过Jupiter验证后结果.不为盈利之用途