目录
- 一、通过类实现一个通用的装饰器,既可以装饰函数,也可以装饰类,既可以装饰有参数的,又可以装饰无参数的。
- 二、请描述__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()
调用这个对象的时候,这个方法:
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的深入学习,文章正在持续缓慢得更新中,想成为一名技术扎实的测试不容易。持续学习,肯钻研,放弃无效社交,不浪费时间很重要。
除标明“图片来自网络”的图片,其它文章中的图片皆为本人所画,计算机知识都一样,如有雷同,纯属巧合。