python:自定义装饰器详解

一、方法对象与方法调用

def test():
    return 1+1

print(test)
print(test())

运行结果:在这里插入代码片
python:自定义装饰器详解_第1张图片
理解装饰器首先要理解方法对象与方法调用,上面的示例中,test是一个方法对象,test()是方法的调用,在理解装饰器的过程中需要注意区分二者。

二、不带参数的装饰器@log1

2.1 代码

def log1(func):
    def log2(*args,**kwargs):
        print("enter function {}()".format(func.__name__))
        return func(*args,**kwargs)
    return log2
    
@log1            
def test(a):
    print("输入参数:",a)

test("法外狂徒张三")

2.2 代码逻辑

这种装饰器有2层

2.2.1 理解装饰器外层方法

python:自定义装饰器详解_第2张图片
外层方法做了3件事:
1、log1接收参数,参数是被修饰的方法对象
2、log1定义了内层方法log2,注意,此处仅仅是定义log2
3、log1返回log2对象

2.2.2 调用被装饰后的方法

@log1
def test(a):
    print("输入参数:", a)

方法对象被装饰后:
被装饰的方法对象 相当于: 装饰器去掉@的部分(被装饰的方法对象)
test 此处相当于log1(test)
调用被装饰后的方法:

test("法外狂徒张三")

test(“法外狂徒张三”)相当于: log1(test)(“法外狂徒张三”)
分析:
log1(test)返回log2方法对象,test(“法外狂徒张三”)相当于: log1(test).log2(“法外狂徒张三”),即调用log2方法

2.2.4 理解log2方法的调用

python:自定义装饰器详解_第3张图片
log1(test).log2(“法外狂徒张三”):
1、接收用户输入的参数"法外狂徒张三"
2、执行print(“enter function {}()”.format(func.name))
3、调用原来的函数,test(“法外狂徒张三”),并返回结果

2.3运行结果

enter function test()
输入参数: 法外狂徒张三

三、带参数的装饰器@out(“哈哈”)

3.1 代码

def out(input_str):
    def log1(func):
        def log2(*args, **kwargs):
            print(input_str)
            print("enter function {}()".format(func.__name__))
            return func(*args, **kwargs)
        return log2
    return log1

@out("哈哈")
def test(a):
    print("输入参数:", a)

test("法外狂徒张三")

3.2 代码逻辑

这种装饰器有3层

3.2.1 理解装饰器外层方法

python:自定义装饰器详解_第4张图片

3.2.2 调用被装饰后的方法

被装饰的方法对象 相当于: 装饰器去掉@的部分(被装饰的方法对象)

@out("哈哈")
def test(a):
    print("输入参数:", a)

方法对象被装饰后:
test 相当于: out(“哈哈”)(test)
调用被装饰后的方法:

test("法外狂徒张三")

test(“法外狂徒张三”)相当于: out(“哈哈”)(test)(“法外狂徒张三”)
分析:
out(“哈哈”)返回log1方法对象,此处相当于: out(“哈哈”).log1(test)(“法外狂徒张三”)
log1(test)返回log2方法对象,此处相当于: out(“哈哈”).log1(test).log2(“法外狂徒张三”),即调用log2方法
执行print(input_str)
执行print(“enter function {}()”.format(func.name))
调用被装饰的函数,test(“法外狂徒张三”),并返回结果

3.3运行结果

python:自定义装饰器详解_第5张图片

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