zoukankan      html  css  js  c++  java
  • 【python基础学习】基础重点难点知识汇总

    python中decorator装饰器

    语法示例:

    @decorator

    什么是装饰器:

    问题:
    定义一个函数后
    在运行时动态增加功能
    又不想改动函数本身的代码

    示例:

    # 希望对下列函数调用增加log功能,打印出函数调用:
    def f1(x):
        return x*2
    def f2(x):
        return x*x
    def f3(x):
        return x*x*x

    方法1:直接修改原函数的定义

    def f1(x):
        print('call f1')
        return x*2
    def f2(x):
        print('call f2')
        return x*x
    def f3(x):
        print('call f3')
        return x*x*x

    有没有更简单的方法?

    高阶函数
    1. 可以接受函数作为参数
    2. 可以返回函数
    是否可以接受一个函数,对其进行包装,然后返回一个新函数?

    方法2:通过高阶函数返回新函数(装饰器函数):

    def f1(x):
        return x*2
    def new_fn(f):
        def fn(x):
            print('call'+f.__name__+'()')
            return f(x)
        return fn

    调用1:

    g1 = new_fn(f1)
    print( g1(5) )

    调用2:

    f1 = new_fn(f1)
    print( f1(5) )

    装饰器:

    python内置@语法就是为了简化装饰器调用

    @new_fn
    def f1(x):
        return x*2

    等同于:

    def f1(x):
        return x*2
    f1 = new_fn(f1)

    装饰器的作用:

    可以极大简化代码,避免每个函数编写重复性的代码
        打印日志:@log
        检测性能:@performance
        数据库事务:@transaction
        URL路由:@post('/register')

    装饰器示例:

    1. 如果自定义函数存在两个形参,上述装饰器函数内部固定写了一个形参,会出现错误怎么办:

    @new_fn
    def add(x,y):
        return x+y
    # 这里会出现错误,所以需要更改 new_fn 函数如下:
    def new_fn(f):
        def fn(*args, **kwargs):
            print('call'+f.__name__+'()')
            return f(*args, **kwargs)
        return fn

    2. 请编写一个@performance,它可以打印出函数调用的时间。计算函数调用的时间可以记录调用前后的当前时间戳,然后计算两个时间戳的差。

    import time
    def performance(f):
        def fn(*args, **kw):
            t1 = time.time()
            r = f(*args, **kw)
            t2 = time.time()
            print 'call %s() in %fs' % (f.__name__, (t2 - t1))
            return r
        return fn
    
    @performance
    def factorial(n):
        return reduce(lambda x,y: x*y, range(1, n+1))
    print factorial(10)

    3.上述装饰器函数只能接受一个函数参数,如果装饰器函数需要传入额外的参数怎么办?

    @log('DEBUG')
    def my_func():
        pass

    把上面的定义翻译成高阶函数的调用,就是:

    my_func = log('DEBUG')(my_func)

    上面的语句看上去还是比较绕,再展开一下:

    log_decorator = log('DEBUG')
    my_func = log_decorator(my_func)

    上面的语句又相当于:

    log_decorator = log('DEBUG')
    @log_decorator
    def my_func():
        pass

    所以,带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数:

    def log(prefix):
        def log_decorator(f):
            def wrapper(*args, **kw):
                print '[%s] %s()...' % (prefix, f.__name__)
                return f(*args, **kw)
            return wrapper
        return log_decorator
    
    @log('DEBUG')
    def test():
        pass
    print test()

    上述第二个例子:@performance只能打印秒,请给 @performace 增加一个参数,允许传入's'或'ms':

    import time
    import functools
    def performance(unit):
        def perf_decorator(f):
            @functools.wraps(f)
            def wapper(*args, **kw):
                t1 = time.time()
                r = f(*args, **kw)
                t2 = time.time()
                t = (t2 - t1) * 1000 if unit=='ms' else (t2 - t1)
                print 'call %s() in %f %s' % (f.__name__, t,unit)
                return r
            return wapper
        return perf_decorator
    
    @performance('ms')
    def factorial(n):
        return reduce(lambda x,y: x*y, range(1, n+1))
    print factorial(10)
    print factorial.__name__

    完善的装饰器写法:

  • 相关阅读:
    投资理财知识小结1
    iOS中异常处理机制使用小结
    iOS中NSBundle使用小结
    ant design vue a-cascader 级联选择器 数据回显
    hbase数据存储及数据访问原理
    第15章: Prometheus监控Kubernetes资源与应用
    第14章:部署Java网站项目案例
    第13章:Kubernetes 鉴权框架与用户权限分配
    第12章:有状态应用部署
    第11章:Pod数据持久化
  • 原文地址:https://www.cnblogs.com/jiangxiaobo/p/11777294.html
Copyright © 2011-2022 走看看