Python3函数之装饰器应用
Python3函数之装饰器应用
夏洛特_ 发表于2年前
Python3函数之装饰器应用
  • 发表于 2年前
  • 阅读 24
  • 收藏 0
  • 点赞 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)
def add(x, y):
    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
def add(x: int, y: int):
    return x + y

2.自己实现partial函数

def partial(fn, **p_kwargs):
    @wraps(fn)
    def wrap(*args, **kwargs):
        return fn( *args, **p_kwargs, **kwargs)
    return wrap
def add(x, y):
    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 = []
    def add(e):
        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
    
    return add, pop
add, pop = heap()
import datetime

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

 

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 2
博文 79
码字总数 70704
×
夏洛特_
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: