Python装饰器

什么是装饰器

在不改变源代码的基础上增加新的功能

装饰器使用前提

1、存在闭包(用于扩展新的功能)

2、待扩展的普通函数 (目的就是不改变该函数,还增加新的功能)

装饰器的语法格式

@闭包外层函数名    
# 此处的作用是使用xxx闭包 装饰 func_xxx 函数,给其扩展功能
def func_xxx():
    ...

装饰器的基本使用

def function_out(func):
    def function_in():
        """新功能函数代码"""
        print("请验证登录")
        func()
    return function_in


@function_out
def login():
    print("登录成功")

"""
核心代码:login=function_out(login)
执行顺序,从右向左
将login函数当作参数传入闭包函数中
此时,login的功能已经被加载进入内存给到func形式参数
再将闭包函数中的新功能返回给login
当再调用login函数,程序开始执行
从function_in处开始执行,这时的function_in里面执行的是新功能的代码
新功能的代码执行结束后,再调用内存中的func()函数,继续执行之前的代码
而装饰器@function_out==(login=function_out(login))
"""

#login=function_out(login)
login()

关于带参数和带返回值的方法如何修饰 

装饰器的作用应该是修饰函数,所以应该为函数量身定制,该传参的地方传参,该return的地方return

一个通用版的装饰器

# 闭包函数 function_out 为外层
def function_out(func):
    # inner 为内层函数
    def function_in(*args, **kwargs):
        print("正在进行验证 ....")
        # func ---> login
        return func(*args, **kwargs)

    return function_in


# 定义login 函数
# login = function_out(login)
@function_out
def login(*args, **kwargs):
    print("---开始登录---")
    return 10


# 调用login函数
result = login(10,20,c=100)
print(result)

将装饰器再进行闭包操作(这种方法被称为工厂模式)

def test_arg(s="hello"):
    # 闭包函数 function_out 为外层
    def function_out(func):
        # inner 为内层函数
        def function_in(a):
            print("正在进行验证 ....,a = ", a, s)
            # func ---> login
            return func(a)

        return function_in

    return function_out


# 定义login 函数
# login = function_out(login)

# 下面的装饰过程
# 1. 调用test_arg("loginxx")
# 2. 将步骤1得到的返回值,即function_out返回, 然后function_out(login)
# 3. 将function_out(login)的结果返回,即function_in
# 4. 让login = function_in,即login现在指向function_in
@test_arg("loginxx")
def login(a):
    print("---开始登录---, a = ", a)
    return a

# 下面的装饰过程
# 1. 调用test_arg("registeryy")
# 2. 将步骤1得到的返回值,即function_out返回, 然后function_out(register)
# 3. 将function_out(register)的结果返回,即function_in
# 4. 让register = function_in,即register现在指向function_in
@test_arg("registeryy")
def register(a):
    print("---开始注册---, a = ", a)


# 调用login函数,实质上调用 function_in --> login
result = login(10)
print("result = ", result)

# 调用register,实质上先调用 function_in --> register
register(100)

多重装饰器

给一个函数进行多次装饰

装饰原则

就近原则(靠近待装饰函数的先装饰)

因为装饰器的下面必须是一个函数

多个装饰器装饰一个函数

# 模拟实现文字加粗的装饰器
def makeBlod(func):
    # 内层函数,实现文字加粗
    def wrapped():
        return "" + func() + ""

    return wrapped


# 模拟实现文字倾斜的装饰器
def makeItalic(func):
    def wrapped():
        return "" + func() + ""

    return wrapped



# 先使用 makeItalic 装饰器,再使用 makeBlod 装饰器
@makeBlod
@makeItalic
def test3():
    return "hello world -3"


# 打印输出

print(test3())

Python装饰器_第1张图片

类装饰器

使用一个类来为函数装饰 

通过__call__内置函数来实现类装饰器的使用,执行过程类似与函数,不用闭包

class Test:
    def __init__(self, func):
        print("========初始化=========")
        self.func = func
        # 可以发现对象初始化的时候login已经进入对象的内存空间中了
        print(self.func)

    def run(self):
        """可以发现,自己写的函数不会起到装饰的作用,因为没有调用"""
        print("===========正在进行装饰==========")

    def __call__(self, *args, **kwargs):
        print("==========正在验证==========",self.func)
        self.func()


"""
@ Test==login=Test(login)
将执行后对象返回给login
而login()函数已经被传入对象的内存空间中
交给__call__内置函数执行
"""


@Test
def login():
    print("=======正在登录========")


login()

你可能感兴趣的:(python,开发语言)