python装饰器

Posted 月疯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python装饰器相关的知识,希望对你有一定的参考价值。

1、装饰定义:

#闭包基础上做了一个升级就是装饰器
'''
判断用户登录状态
1、装饰器,函数作为参数
2、要有闭包的特点
'''

def func(number):
    a = 100

    def inner_func():
        #对a进行修改
        nonlocal a
        nonlocal number
        for i in range(number):
            number += 1

        print('修改后a的值',a)

    return inner_func

#装饰器
def test():
    print('test')

def yuck(f):
    print(f)
    f()


if __name__ == '__main__':
    f = func(6)
    f()

    yuck(test)

F:\\开发工具\\pythonProject\\basepython\\venv\\Scripts\\python.exe F:/开发工具/pythonProject/basepython/day01/装饰器.py
修改后a的值 100
<function test at 0x000001F1A9DFDF70>
test

Process finished with exit code 0

注释:

因为nonlocal是在Python3.0中新增的关键字,python2.x不提供支持,文中提出在Python2.x解决嵌套函数引用外部变量的方法只有使用global 关键字定义全局变量

#定义一个装饰器


def decorate(func):
    a = 100

    def wrapper():
        func()
        print('------------->1')
        print('-------------->2',a)

    return wrapper

#使用装饰器,调用上面的函数
@decorate
def house():
    print('土房子')



if __name__ == '__main__':
    house()
F:\\开发工具\\pythonProject\\basepython\\venv\\Scripts\\python.exe F:/开发工具/pythonProject/basepython/day01/装饰器定义.py
土房子
------------->1
-------------->2 100

Process finished with exit code 0
'''
默认执行decorate函数
1、house被称为装饰函数
2、将被装饰函数作为参数传递给装饰器decorate
3、执行decorate函数
4、将装饰函数的返回值又赋值给house
'''

 2、装饰器方法传递参数

参数万能接受(*args,**kwargs)

*args接受多个参数

**kwargs可以接收字典

#登录校验
import time


def decorate(func):

    def wrapper(*args,**kwargs):
        print('正在校验。。。。')
        time.sleep(2)
        print('校验完毕。。。。')
        #调用原函数
        func(*args,**kwargs)
    return wrapper
#传入整型
@decorate
def f1(n):
    print('---------1',n)
#传入字符串
@decorate
def f2(name,n):
    print('-----------2',name,n)
#传入一个列表

@decorate
def f3(students,clazz = 'huitao'):
    print(clazz)
    for stu in students:
        print('-----------3', stu)
        
@decorate
def f4():
    print('-------4')

#参数的个数不确定,需要可变参数,*args;万能装饰器
#接受关键字的参数**kwargs,传递字典
if __name__ =='__main__':
    student = ['huitao', 'weiping', 'qiwei']
    f1(4)
    f2('huitao',5)
    f3(student)
F:\\开发工具\\pythonProject\\basepython\\venv\\Scripts\\python.exe F:/开发工具/pythonProject/basepython/day01/装饰器传递参数.py
正在校验。。。。
校验完毕。。。。
---------1 4
正在校验。。。。
校验完毕。。。。
-----------2 huitao 5
正在校验。。。。
校验完毕。。。。
huitao
-----------3 huitao
-----------3 weiping
-----------3 qiwei

Process finished with exit code 0

传递参数,依次打印出来。

3、装饰器传递参数(在装饰器外层,再加一层方法,接受参数)

#定义装饰器
#装饰器带参数,就是装了三层
#pychar代码缩进,先鼠标选中,然后按下tab键
def out(a): #接受装饰器参数
    def decorate(func):#接受函数

        def wrapper(*args,**kwargs):#接受函数的参数
            func(*args,**kwargs)
            print('-----------',a)
        return wrapper
    return decorate


@out(a = 10)
def house():
    print('开始装修')


if __name__ == '__main__':
    house()
F:\\开发工具\\pythonProject\\basepython\\venv\\Scripts\\python.exe F:/开发工具/pythonProject/basepython/day01/带参数的装饰器.py
开始装修
----------- 10

Process finished with exit code 0

4、函数的多层装饰器

#装饰器

def buss1(func):
    print('----1start')
    def wrapper(*args,**kwargs):
        print('装饰器1')
        func(*args,**kwargs)

    print('----1end')
    return wrapper


def buss2(func):
    print('----2start')
    def wrapper(*args,**kwargs):
        print('装饰器2')
        func(*args,**kwargs)

    print('----2end')
    return wrapper


#添加俩个装饰器
@buss1
@buss2
def house():
    print('开始做装修')


if __name__ == '__main__':
    house()
F:\\开发工具\\pythonProject\\basepython\\venv\\Scripts\\python.exe F:/开发工具/pythonProject/basepython/day01/多层装饰器.py
----2start
----2end
----1start
----1end
装饰器1
装饰器2
开始做装修

Process finished with exit code 0

5、装饰器使用场景

付款登录,要付款就先登录成功。

#开发:登录验证
import time
isLogin = False #默认不登录

#登录方法
def login():
    username = input('输入用户名:')
    password = input('输入密码:')
    if username == 'admin' and password =='123456':
        return True
    else:
        return False


#定义一个装饰器,付款登录
def login_base(func):

    def wapper(*args,**kwargs):
        # 声明了才可以对isLogin进行修改
        global isLogin
        if  isLogin:
            func(*args, **kwargs)
        else:
            #跳转登录
            isLogin = login()
            print('result:',isLogin)
    return wapper

#付款
@login_base
def pay(money):
    print('正在付款,付款金额'.format(money))
    print('付款中....')
    time.sleep(2)
    print('付款成功.....')

if __name__ == '__main__':
    pay(10000) #调用第一次因为没有登录 (wrapper)
    pay(8000)#因为登录成功了,所以直接登录

打印:

F:\\开发工具\\pythonProject\\basepython\\venv\\Scripts\\python.exe F:/开发工具/pythonProject/basepython/day01/装饰器应用.py
输入用户名:admin
输入密码:123456
result: True
正在付款,付款金额8000
付款中....
付款成功.....

Process finished with exit code 0

以上是关于python装饰器的主要内容,如果未能解决你的问题,请参考以下文章

python装饰器

Python的闭包和装饰器

python装饰器迭代器生成器闭包等等

浅谈对python装饰器的理解

Python之闭包and装饰器

python测试开发(02-闭包函数+装饰器)