文档章节

Python3函数之装饰器应用

夏洛特_
 夏洛特_
发布于 2016/10/28 06:57
字数 644
阅读 24
收藏 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
博文 80
码字总数 72279
作品 0
宁德
程序员
转载:唐磊的个人博客《python中decorator详解》【转注:深入浅出清晰明了】

转载请注明来源:唐磊的个人博客《python中decorator详解》 前面写python的AOP解决方案时提到了decorator,这篇文章就详细的来整理下python的装饰器——decorator。 python中的函数即objects...

laugh2last
2015/08/17
0
0
深入浅出 Python 装饰器:16 步轻松搞定 Python 装饰器

Python的装饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西。虽然好像,他们要干的事都很相似——都是想...

大数据之路
2015/07/12
0
2
Python - 装饰器使用过程中的误区

曾灵敏 — APRIL 27, 2015 装饰器基本概念 大家都知道装饰器是一个很著名的设计模式,经常被用于AOP(面向切面编程)的场景,较为经典的有插入日志,性能测试,事务处理,, 等。 Python语言本...

OneAPM1
2015/05/08
0
1
设计模式之:理解 Python 中的装饰器

1、问题 文章先由stackoverflow上面的一个问题引起吧,如果使用如下的代码: @makebold @makeitalic def say(): return "Hello" 打印出如下的输出: <b><i>Hello<i></b> 你会怎么做?最后给出......

大数据之路
2013/07/22
0
0
Python基础——装饰器、模块(0417)

一、Python基础——复习 1、字符串的常用操作 2、列表的常用操作 3、字典的常用操作 二、Python——装饰器:函数可以是变量 1、Python是一种面向对象的编程语言,在Python中所有的都可以是Pyt...

python初雪之路
04/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

函数调用约定 (cdecl stdcall)

函数调用约定 (cdecl stdcall) 在 C 语言里,我们通过阅读函数声明,就知道怎么携带参数去调用函数,也能在函数体定义内使用这些参数。但是 CPU 并不直接完成函数调用的传参操作,这需要人为...

傅易
4分钟前
0
0
Python 核心编程 (全)

浅拷贝和深拷贝 1.浅拷贝:是对于一个对象的顶层拷贝,通俗的理解是:拷贝了引用,并没有拷贝内容。相当于把变量里面指向的一个地址给了另一个变量就是浅拷贝,而没有创建一个新的对象,如a=b...

代码打碟手
6分钟前
0
0
mysql5.7 修改datadir

mysql 的默认存储路径为 /var/lib/mysql ,修改后为 /data/mysql 关闭服务 service mysql stop 复制mysql 数据文件到新的目录 cp -rp /var/lib/mysql /data 查看原目录的权限,如果新目...

hotsmile
23分钟前
0
0
证书安装指引之Tomcat 证书部署

Tomcat 证书部署 0 申请证书 1 获取证书 如果申请证书时有填写私钥密码,下载可获得Tomcat文件夹,其中有密钥库 www.domain.com.jks; 如果没有填写私钥密码,证书下载包的Tomcat文件夹中包括...

吴伟祥
27分钟前
0
0
ConcurrentHashMap1.7和1.8的底层不同实现

1.Hashmap和HashTable在线程安全方面的优劣? Hashmap多线程会导致HashMap的Entry链表形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,就会产生死循环获取Entry。 Hash...

刘祖鹏
43分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部