码迷,mamicode.com
首页 > 编程语言 > 详细

【python基础学习】基础重点难点知识汇总

时间:2019-11-01 16:14:32      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:nbsp   当前时间   编写   actor   gis   示例   tool   fun   增加   

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__

 

完善的装饰器写法:

 

【python基础学习】基础重点难点知识汇总

标签:nbsp   当前时间   编写   actor   gis   示例   tool   fun   增加   

原文地址:https://www.cnblogs.com/jiangxiaobo/p/11777294.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!