前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Py测开《通过类实现一个通用的装饰器》

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

作者头像
清菡
发布2022-03-30 09:16:05
1700
发布2022-03-30 09:16:05
举报
文章被收录于专栏:清菡软件测试清菡软件测试

目录

  • 一、通过类实现一个通用的装饰器,既可以装饰函数,也可以装饰类,既可以装饰有参数的,又可以装饰无参数的。
  • 二、请描述__new__、__str__、__repr__、__call__分别在什么情况下会被触发?
  • 三、总结

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

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

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

代码语言:javascript
复制


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方法。


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

代码语言:javascript
复制


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()调用这个对象的时候,这个方法:

代码语言:javascript
复制

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

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

代码语言:javascript
复制

    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()就能够拿到了。

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

代码语言:javascript
复制


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方法。

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

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

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

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

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

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

三、总结

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

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


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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 清菡软件测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、通过类实现一个通用的装饰器,既可以装饰函数,也可以装饰类,既可以装饰有参数的,又可以装饰无参数的。
  • 二、请描述__new__、__str__、__repr__、__call__分别在什么情况下会被触发?
  • 三、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档