Python3函数之装饰器应用
Python3函数之装饰器应用

Python3函数之装饰器应用
• 发表于 2年前
• 阅读 24
• 收藏 0
• 评论 0

## 1.写一个装饰器，对函数的部分或者全部参数做类型检查

``````from functools import wraps

def type_check(*type_args, **type_kwargs):
def dec(fn):
@wraps(fn)
def wrap(*args, **kwargs):
for i, t in enumerate(type_args):
if not isinstance(args[i], t):
print('pos {} argument {} type error'.format(i, args[i]))
return None
for k, t in type_kwargs.items():
if not isinstance(kwargs[k], t):
print('keyword argument {} => {} type error'.format(k, kwargs))
return None
return fn(*args, **kwargs)
return wrap
return dec

@type_check(x=int, y=int)
return x + y``````

``````import inspect

def typed(fn):
@wraps(fn)
def wrap(*args, **kwargs):
for i, param in enumerate(inspect.signature(fn).parameters.values()):
if param.annotation:
if param.name in kwargs.keys():
if not isinstance(kwargs[param.name], param.annotation):
raise TypeError(param.name)
else:
if not isinstance(args[i].param.annotation):
raise TypeError(param.name)
return fn(*args, **kwargs)
return wrap

@typed
return x + y``````

## 2.自己实现partial函数

``````def partial(fn, **p_kwargs):
@wraps(fn)
def wrap(*args, **kwargs):
return fn( *args, **p_kwargs, **kwargs)
return wrap
return x + y``````

## 3.写一个函数，判断两个字典是否相等，字典的value可能为数字、字符串、元组、列表、集合和字典。如果value为列表或字典，需要判断其中两个元素是否相等

``````def dict_eq(a, b):
for k, v in a.items():
if k not in b.keys():
return False
else:
if not isinstance(v, (dict, list)):
if v != b[k]:
return False
if isinstance(v, list):
for i, item in enumerate(v):
if len(b[k]) <= i:
return False
if b[k][i] != item:
return False
if isinstance(v, dict):
ret = dict_eq(v, b[k])
if ret is False:
return ret``````

## 4.模拟一个数据源不断的产生数值，求一段时间内，最大的K个元素

``````import random
import time

def data_source():
while True:
yield random.randint(0, 100)
time.sleep(0.1)
ds = data_source()``````
``````import datetime

def top_k1(k, time=3):
start = datetime.datetime.now()
lst = []
while True:
lst.append(next(ds))
current = datetime.datetime.now()
if (current - start).total_seconds() >= time:
start = current
lst.sort()
ret = []
for _ in range(k):
ret.append(lst.pop())
yield ret
g = top_k1(10)
for _ in range(3):
print(next(g))``````
``````import datetime

def top_k2(k, time=3):
start = datetime.datetime.now()
lst = []
while True:
#lst.append(next(ds))
e = next(ds)
for i, v in enumerate(lst):
if e < v:
lst.insert(i, e)
break
else:
lst.append(e)
current = datetime.datetime.now()
if (current - start).total_seconds() >= time:
start = current
#lst.sort()
ret = []
for _ in range(k):
ret.append(lst.pop())
yield ret``````
``````def heap():
data = []
idx = len(data)
data.append(e)
parent_idx = (idx - 1) // 2
while parent_idx >= 0:
if data[idx] > data[parent_idx]:
data[parent_idx], data[idx] = data[idx], data[parent_idx]
idx = parent_idx
parent_idx = (idx - 1) // 2
else:
break

def pop():
if not data:
return None
if len(data) == 1:
return data.pop()
idx = 0
ret = data[idx]
data[idx] = data.pop()
left_idx = 2 * idx + 1
rigth_idx = left_idx + 1
while left_idx < len(data):
child_idx = left_idx
if rigth_idx < len(data) and data[rigth_idx] > data[left_idx]: # 存在右子节点 并且 右子节点大于左子节点
child_idx = rigth_idx
if data[idx] < data[child_idx]:
data[idx], data[child_idx] = data[child_idx], data[idx]
idx = child_idx
left_idx = 2 * idx + 1
rigth_idx = left_idx + 1
else:
break
return ret

import datetime

def top_k3(k, time=3):
start = datetime.datetime.now()
while True:
current = datetime.datetime.now()
if (current - start).total_seconds() >= time:
start = current
ret = []
for _ in range(k):
ret.append(pop())
yield ret``````

×