MegaMU个人站

欢迎光临

落日黄沙 白帆秋水 你可知谁的记忆在时空里飞?


装饰器入门

目录

在不改变原函数的情况下为原函数扩展

装饰器函数都是要闭包的

向装饰器函数传入要被装饰的函数

被装饰的函数在调用时相当于调用装饰器函数,并向其中传入了被装饰的函数作为参数。

img

无参数

def func_out(func):
    def func_in():
        print('扩展函数')
    	func()
    return func_in

@func_out
def func_main():
    print("主体函数")


func_main()

有参数

参数要层层传递下去

def func_out(func):
    def func_in(obj):
        print('扩展函数')
        func(obj)
    return func_in

@func_out
def func_main(char):
    print("主体函数",char)

func_main('NB')

多参数

def func_out(func):
    def func_in(*args,**kwargs):
        print('扩展函数')
        func(args,kwargs)
    return func_in

@func_out
def func_main(*args,**kwargs):
    print("主体函数",args,kwargs)


func_main('NB'a='NB')

等一下,这样就出问题了!

扩展函数
主体函数 (('NB',), {'a': 'NB'}) {}

所以参数都传进args里面了!

在传参时要用*args**kwargs进行传参。

正确用法

def func_out(func):
    def func_in(*args,**kwargs):
        print('扩展函数')
        func(*args,**kwargs)
    return func_in

@func_out
def func_main(*args,**kwargs):
    print("主体函数",args,kwargs)


func_main('NB',a='NB')

返回值

要想返回值,必须装饰器和主题函数都一起return

def func_out(func):
    def func_in(*args,**kwargs):
        print('扩展函数')
        return func(*args,**kwargs) # 装饰器return 
    return func_in

@func_out
def func_main(*args,**kwargs):
    print("主体函数",args,kwargs)
    return args,kwargs # 函数中的return


print(func_main('NB',a='NB'))

在装饰器上设置外部变量

需要在外面再套层壳

def test(arg):
    print(arg)
    """这里进入正常的装饰器"""
    def func_out(func):

        def func_in(*args,**kwargs):
            print('扩展函数')
            return func(*args,**kwargs)
        return func_in
    return func_out

@test("666")
def func_main(*args,**kwargs):
    print("主体函数",args,kwargs)
    return args,kwargs

print(func_main('NB',a='NB'))

多重装饰器

在前面多加几个装饰器就行啦,靠近被装饰函数的会先被执行(就近原则)

@func_1
@func_2
def function():
    pass

类装饰器

使用类为函数做装饰

# 使用类为函数作装饰
class Test(object):

    def __init__(self):
        print("__init__方法")

    def func(self):
        print("方法1")

test = Test()
test()

执行时会报错TypeError: 'Test' object is not callable

我们为它加上__call__()方法,使它可以被执行。

# 使用类为函数作装饰
class Test(object):

    def __init__(self):
        print("__init__方法")

    def func(self):
        print("方法1")

    def __call__(self, *args, **kwds):
        print("__call__方法")
        
test = Test()
test()

直接调用test()先在它会执行__init__方法,然后执行__call__方法。

# 使用类为函数作装饰

class Test(object):

    def __init__(self,func):
        print("__init__方法",func)

    def func(self):
        print("func方法")

    def __call__(self, *args, **kwds):
        print("__call__方法")
        
@Test
def function():
    print("function函数")

function()

实际上用@Test装饰函数相当于function = Test(function)

之后我们调用的function()实际上是一个类,它执行了自己的__init__方法和__call__方法。

class Test(object):

    def __init__(self,func):
        print("__init__方法",func)
        self.func = func

    def func(self):
        print("func方法")

    def __call__(self, *args, **kwds):
        print("__call__方法")
        self.func()
        
@Test
def function():
    print("function函数")

function()

我们把传入的function储存一下,并在__call__方法中调用

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦