Py测开《通过类实现一个通用的装饰器》

坚持原创输出,点击蓝字关注我吧

a44a85173c4a21ff5a32788d3ecea4fa.png

图片来自网络

目录

  • 一、通过类实现一个通用的装饰器,既可以装饰函数,也可以装饰类,既可以装饰有参数的,又可以装饰无参数的。

  • 二、请描述__new__、__str__、__repr__、__call__分别在什么情况下会被触发?

  • 三、总结

一、通过类实现一个通用的装饰器,既可以装饰函数,也可以装饰类,既可以装饰有参数的,又可以装饰无参数的。

在装饰的时候把原来这个test_01函数,通过test_01=Decorator(test_01)传进去了。通过这个Decorator类,Decorator(test_01)创建对象,传递的参数会被初始化方法init接收。

直接这样装饰,没有定义init方法,运行看下结果:

def single(cls):
    instance={}


    def fun(*args,**kwargs):
        if cls in instance:
            return instance[cls]
        else:
            instance[cls]=cls(*args,**kwargs)
            return instance[cls]
    return fun


@single
class Test:
    pass

# t1=Test()



# @single
# class MyTest:
#     pass



#类实现装饰器

class Decorator:#通过这个类实现装饰器
  def __call__(self, *args, **kwargs):
      print("这个是装饰器里面的功能")





@Decorator#通过这个类Decorator实现装饰器。艾特下这个类,等于在这里做了这个事情:
# test_01=Decorator(test_01)这句代码中Decorator(test_01)是通过这个Decorator类创建了个对象,然后
#让test_01()这个函数接收了。
def test_01():
    print('----原来的功能函数----')

test_01()#调用这个函数,实际上是拿着一个对象在调用,不是调用test_01()函数,
# 也不是调用Decorator类。这个对象是Decorator类创建出来的。
#如果一个类的对象,要想被调用的话,应该定义一个call方法。
43015c65ff50b87dc70bf6ad7750c88b.png

报错了。所以需要定义一个init方法:

def single(cls):
    instance={}


    def fun(*args,**kwargs):
        if cls in instance:
            return instance[cls]
        else:
            instance[cls]=cls(*args,**kwargs)
            return instance[cls]
    return fun


@single
class Test:
    pass

# t1=Test()



# @single
# class MyTest:
#     pass



#类实现装饰器

class Decorator:#通过这个类实现装饰器
  def __init__(self,func):#init方法需要接收一个参数func,接收的就是被装饰的函数
      pass
  def __call__(self, *args, **kwargs):
      print("这个是装饰器里面的功能")





@Decorator#通过这个类Decorator实现装饰器。艾特下这个类,等于在这里做了这个事情:
# test_01=Decorator(test_01)这句代码中Decorator(test_01)是通过这个Decorator类创建了个对象,然后
#让test_01()这个函数接收了。
def test_01():
    print('----原来的功能函数----')

test_01()#调用这个函数,实际上是拿着一个对象在调用,不是调用test_01()函数,
# 也不是调用Decorator类。这个对象是Decorator类创建出来的。
#如果一个类的对象,要想被调用的话,应该定义一个call方法。

Decorator(test_01)这里创建对象的时候传了个参数,这个参数被func接收了。

test_01()调用这个对象的时候,这个方法:

def __call__(self, *args, **kwargs):
      print("这个是装饰器里面的功能")

其实就是相当于这个装饰器函数了:

def fun(*args,**kwargs):
        if cls in instance:
            return instance[cls]
        else:
            instance[cls]=cls(*args,**kwargs)
            return instance[cls]

做了装饰器要做的事情后,想要调用原来的功能函数,还需要调用这个func,那么这个func在函数下面怎么访问的到呢?

想办法把func保存到实例属性里面。通过self.func=func保存到实例属性里面。直接self.func()就能够拿到了。

这个函数已经完全放到装饰器里面来执行了:

def single(cls):
    instance={}


    def fun(*args,**kwargs):
        if cls in instance:
            return instance[cls]
        else:
            instance[cls]=cls(*args,**kwargs)
            return instance[cls]
    return fun


@single
class Test:
    pass

# t1=Test()



# @single
# class MyTest:
#     pass



#类实现装饰器

class Decorator:#通过这个类实现装饰器
  def __init__(self,func):#init方法需要接收一个参数func,接收的就是被装饰的函数
      self.func = func
  def __call__(self, *args, **kwargs):
      print("这个是装饰器里面的功能")
      self.func()
      print('--装饰器--功能2--')


@Decorator#通过这个类Decorator实现装饰器。艾特下这个类,等于在这里做了这个事情:
# test_01=Decorator(test_01)这句代码中Decorator(test_01)是通过这个Decorator类创建了个对象,然后
#让test_01()这个函数接收了。
def test_01():
    print('----原来的功能函数----')

test_01()#调用这个函数,实际上是拿着一个对象在调用,不是调用test_01()函数,
# 也不是调用Decorator类。这个对象是Decorator类创建出来的。
#如果一个类的对象,要想被调用的话,应该定义一个call方法。
1e8461412e9acd753a7b5751f776293f.png

二、请描述__new__、__str__、__repr__、__call__分别在什么情况下会被触发?

__new__:调用一个类去创建实例对象的时候,实例对象是__new__出来的。创建出来实例对象,再交给__init__做初始化。

如果__new__方法没有创建出来实例对象,__init__没有对象就没办法做初始化了。

__str__:print打印的时候会触发。format处理一个对象,也会被触发。通过__str__这个内置函数去转换一个对象的时候,也会触发__str__这个方法。

__repr__:在交互环境下直接输入这个repr(对象),也会触发__repr__方法。通过__repr__这个内置函数去处理,也会触发这个方法。

a87fb48d0ff34105593b7f7580a016ac.png

__call__:一个对象被调用的时候,它才会被触发这个__call__方法。

三、总结

首先分清四个方法的用法,接下来写平台一定会用到这些所学的知识。

Jmeter、网络基础、计算机原理、Linux、Mysql的深入学习,文章正在持续缓慢得更新中,想成为一名技术扎实的测试不容易。持续学习,肯钻研,放弃无效社交,不浪费时间很重要。


除标明“图片来自网络”的图片,其它文章中的图片皆为本人所画,计算机知识都一样,如有雷同,纯属巧合。

公众号 清菡软件测试 首发,更多原创文章:清菡软件测试 160+ 原创文章,欢迎关注、交流,禁止第三方擅自转载。如有转载,请标明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清菡软件测试

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值