26.Python进阶_装饰器装饰类08

本文深入探讨了Python中装饰器装饰类的原理和实现方法,包括装饰器如何影响类对象的创建过程,如何通过修改装饰器内部函数或类装饰器的call方法来正确创建和返回类对象,以及如何在装饰器中给类对象设置属性。
摘要由CSDN通过智能技术生成

之前我们看的是函数作为装饰器,类可以作为装饰器,
被装饰的对象之前学习的都是函数,今天我们来看一下装饰器装饰类;

def test(func):
    def test_in():
        print("----test_in-----")
        func()
    return test_in

@test    #Hero=test(Hero)
class Hero(object):
    def fun(self):
        print('----装饰器装饰类-----')


h=Hero()
print(h)

运行结果:
----test_in-----
None

发现为何执行结果为None,我们来看一下执行过程:

1.执行h=Hero()的过程实际并不是创建对象,而是相当于去执行装饰器;执行Hero相当于去执行test(Hero);
2.执行test(func)时外部函数返回值为内部函数体,test_in,。此时会去执行test_in()
3.test_in的返回值会指向h,但是内部函数test_in没有返回值,所以打印h会输出None;

我们想要在执行h=Hero()时创建对象,应该在闭包中进行创建对象,即test_in函数体中进行创建对象

以上改造如下:

def test(func):
    def test_in():
        print("----test_in-----")
        f=func()  #实际是创建对象
        return f   #返回对象
    return test_in

@test    #Hero=test(Hero)
class Hero(object):
    def fun(self):
        print('----装饰器装饰类-----')


h=Hero()   
h.fun()

运行结果:

----test_in-----
----装饰器装饰类-----

还可以装饰器中给对象设置属性:

def test(func):
    def test_in():
        print("----test_in-----")
        setattr(func,'name','静静')  #使用setattr设置属性
        f=func()  #实际是创建对象
        return f   #返回对象
    return test_in

@test    #Hero=test(Hero)
class Hero(object):
    def fun(self):
        print('----装饰器装饰类-----')


h=Hero()
h.fun()
print(h.name)

运行结果:

----test_in-----
----装饰器装饰类-----
静静

再看一下类装饰器装饰类:

class test():
    def __init__(self,func):
        print('----init----')
        self.func=func
    def __call__(self, *args, **kwargs):
        print('---call---')
        self.func()

@test    #Hero=test(Hero)
class Hero(object):
    def fun(self):
        print('----装饰器装饰类-----')


h=Hero()
h.fun()

运行报错:

----init----
---call---
Traceback (most recent call last):
  File "C:/workspace/pythonTest/pythonDemo/0830_deo.py", line 27, in <module>
    h.fun()
AttributeError: 'NoneType' object has no attribute 'fun'

可见同样是缺少返回值:

call方法中将被装饰函数返回:

class test():
    def __init__(self,func):
        print('----init----')
        self.func=func
    def __call__(self, *args, **kwargs):
        print('---call---')
        return self.func()  #返回

@test    #Hero=test(Hero)
class Hero(object):
    def fun(self):
        print('----装饰器装饰类-----')


h=Hero()
h.fun()

运行结果:

----init----
---call---
----装饰器装饰类-----

可见装饰类和装饰函数的区别是:
1.类需要创建对象,因此需要将类对象返回,即需要在函数装饰器的内部函数中返回或者在类装饰器的call方法中将类对象返回;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值