python 装饰器

ε祈祈猫儿з 提交于 2019-12-02 22:51:57

1. 装饰器

装饰器其实是一个函数,作用是装饰其他函数装饰器的特点:1. 不改变被装饰的函数的源代码的情况下添加函数的功能             2. 不改变被装饰的函数的调用方式装饰器的组成方式:高阶函数+嵌套函数

1.1 高阶函数

高阶函数,以一个函数名作为参数,传递给另一个函数,这个函数就是高阶函数。

print(abs(-10))  # abs,内置函数,返回一个数的绝对值

def test(num,func):  # 高阶函数,以一个函数名作为参数,传递给另一个函数
    absNum = func(num)  # 调用函数
    print(absNum)

test(-2,abs)     # 注意,这里写的是abs,是函数名,没有加()

map和lambda函数

map函数是一个内置的函数,它也是一个高阶函数,配合lambda(匿名函数),可以实现很多功能

lambda函数

lambda是匿名函数,没有函数名,最多支持三元运算,是一种简单的函数

三元运算:

a,b,c = 1,2,3
d = 5 if a>b else c  # 如果条件成立,d=5,否则就 =c 

lambda函数,以:分开,:左边写参数(可以多个,以‘,’分割),右边写函数体

a = lambda n:n*2 if n<10 else n
print(a(6))

b = lambda x,y:x+y
print(b(1,1))
'''
上面的b,等同于:
def b(x,y):
    return x+y
'''

map函数

map函数是一个高阶函数; 语法:map(function, iterable, ...),对iterable对象的每个元素执行function,然后将结果放到map对象中

# 通过map lambda 对一个列表的每个元素求平方
num = [1,2,3,4,5]
n = map(lambda x:x**2,num)
print(list(n))   # 转换成list打印出来

1.2 嵌套函数

嵌套函数,顾名思义,函数内部嵌套了一层或多层函数

def test():
    print('this is outer func')
    def test2():  # 嵌套的函数
        print('this is inner func')
    test2()      # 在test中调用内层函数
test()

1.3 装饰器

python的内存分配机制:1. 普通变量内存分配,例如:x=1  y=x    在这个例子中,x相当于一个门牌号,指向一个内存地址,内存里面放着1,    而y=x相当于这个内存加了一个门牌号:y ,它俩实际上指向一个内存地址,    当x,y都不再调用1时,这个内存才会被定期的内存刷新清理掉2. 函数的内存分配:例如 def get():                            pass   这个例子中,函数名get是一个内存地址,内存里存的是函数的内容,在内存中只是作为字符串存放,这里就是pass,   所以print(get)得到的是一个内存地址,而get()才是真的执行了函数的内容下面给test1添加一个用来计时的装饰器:timer
 1 import time
 2 from time import sleep
 3 
 4 def timer(func):   # 高阶函数:以函数作为参数
 5     def deco(*args,**kwargs):    # 嵌套函数,在函数内部以 def 声明一个函数,接受 被装饰函数的所有参数
 6         time1 = time.time()
 7         func(*args,**kwargs)
 8         time2 = time.time()
 9         print('func elapsed %s' %(time2-time1))
10     return deco    # 注意,返回的函数没有加括号!所以返回的是一个内存地址,而不是函数的返回值
11 
12 @timer   # 装饰器,放在被装饰函数的顶部,等同于: test1 = timer(test1) = deco
13 def test1(name):
14     print('test1 is running, will sleep 1 seconds...')
15     sleep(1)
16     print('test1 is over.',name)
17 
18 test1('wwwww')

上述代码执行步骤:

1. 执行第4行代码。创建变量timer,将timer的函数体存入内存

2. 执行12行代码。相当于test1 = timer(test1),此时调用了timer函数,将会执行第5行:创建变量deco:将deco的函数体存入内存;继续执行第10行代码,将返回值赋值给test1,此时test1就相当于deco

3. 执行18行代码。根据上述第2步,test1相当于deco,所以此时就相当于执行deco('wwwww')

4. 所以,执行第5行代码,开始执行deco('wwwww'),然后是第6行、第7行:在第7行时,func这个形参是第4行得来的,在上述第2步的时候,将test1传递给了timer,所以这里的func就是test1

5. 因此,执行test1(),所以代码执行第14-16行,然后继续回到第8行、第9行,完成函数deco()的执行。

1.4 带参数的装饰器

user,passwd = 'alex','123'

def auth(log_type):
    print(log_type)
    def outwrapper(func):   # 不带参数的装饰器应该从这里开始,带了参数相当于外面多了一层函数
        def wrapper(*args,**kwargs):
            username = input('username:')
            password = input('password:')
            if username == user and password == passwd:
                res = func(*args,**kwargs)
                return res
            else:
                print('username or Password is wrong.')
        return wrapper
    return outwrapper
'''
正常的装饰器不带括号: @auth 等同于 index = auth(index) 
而如果加了括号(此处带了一个关键字参数),则执行此装饰器(本质是函数),将被装饰函数作为参数传递给里层的函数
'''
@auth(log_type = 'local')  # index = auth(log_type='local') = outwrapper(index) =  wrapper
def index():
    print('welcome to index page.')
    return 1

index()

 


 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!