一个类作为装饰器 装饰另一个类的实例的方法(类的函数)

在类中写的实例方法, 对于类来说,叫做类的函数

class Decorator:
    def __init__(self, func):
        print('func=', func)
        print('init Decorator obj=', self)
        self.func = func
        print(f'{self}.func=', self.func)
        print(f'dir({self})=', dir(self))
    
    def __call__(self, *args, **kwargs):
        print('self=', self)
        print('args= ', args)
        print('call {}'.format(self.func.__name__))
        print(self.func)
        return self.func(*args, **kwargs)
    
    
class AAA:
    def __init__(self, name):
        print('init AAA obj=', self)
        self.name = name
    
    # Decorator装饰类调用(实例化),将AAA.get_args属性指向的get_args(self,args)函数(在类的命名空间中,所有实例方法对于类来说都是函数)作为了入参
    # 由于装饰器会重新给AAA.get_args属性重新赋值,所以为了赋值前AAA.get_args属性所指向的get_args(self,args)函数不被丢失,需要在Decorator类的__init__属性所指向的__init__()函数中
    # 将get_args(self,args)函数传给func行参,并通过self.func这个实例属性将func形参接受到的实参(get_args(self,args))保存下来,以防止get_args(self,args)丢失了.以便后用.
    
    # 这里的get_args(self, args)函数(函数也是对象)的引用是AAA.get_args
    # 这里的get_args,在被@Decorator调用之前,叫做AAA.get_args ,在被@Decorator调用之后再复制给get_args,那么新的get_args还是AAA.get_args这个属性,只是
    # 被@Decorator调用之后,AAA.get_args属性指向的对象(或者引用的对象)改变了, 改变成了AAA的一个实例了.
    @Decorator
    def get_args(self, args):
        print(f'print self and args', self, args)
        return args
    
    # 可以使用如下代码,代替上方装饰器装饰的代码,来理解这样的语法糖,是一摸一样的
    # def get_args(self, args):
    #     print(f'print self args', self, args)
    #     return args
    # print(2222, get_args)
    # get_args = Decorator(get_args)


if __name__ == '__main__':
    pass
    print(dir(AAA))
    print('1111111, AAA.get_args:', AAA.get_args)
    aaa = AAA('zhangsan')
    print(f'{aaa}.get_args=', aaa.get_args)
    print(f'{aaa}.get_args()', aaa.get_args(aaa, 'args1'))  # 这里AAA类的实例aaa调用get_args时,需要显示的传递self为aaa自己,因为代码执行到这句时,aaa.get_args已经引用了Decorator的实例


    

func= <function AAA.get_args at 0x00000281461BFB50>
init Decorator obj= <__main__.Decorator object at 0x00000281461A2B60>
<__main__.Decorator object at 0x00000281461A2B60>.func= <function AAA.get_args at 0x00000281461BFB50>
dir(<__main__.Decorator object at 0x00000281461A2B60>)= ['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'func']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_args']
1111111, AAA.get_args: <__main__.Decorator object at 0x00000281461A2B60>
init AAA obj= <__main__.AAA object at 0x00000281461A2C20>
<__main__.AAA object at 0x00000281461A2C20>.get_args= <__main__.Decorator object at 0x00000281461A2B60>
self= <__main__.Decorator object at 0x00000281461A2B60>
args= (<__main__.AAA object at 0x00000281461A2C20>, 'args1')
call get_args
<function AAA.get_args at 0x00000281461BFB50>
print self and args <__main__.AAA object at 0x00000281461A2C20> args1
<__main__.AAA object at 0x00000281461A2C20>.get_args() args1

 

posted @ 2023-10-19 00:17  fangpinz  阅读(44)  评论(0)    收藏  举报