实习做一个自动化测试项目的时候看到大佬代码:
d = u2.connect() #该方法返回一个UIAutomatorServer类的实例
d(discription = 'Books').click() # ???wtf,怎么对象名字后面带个括号,什么操作?
为了搞懂这个原因,我把代码里原来正确的参数description随便改成了一个错的,比如d(abc='1'),根据报错的信息一步步地查看相关的代码部分,然后结合百度找到了这个用法,其实就是python的__call__()方法:
在创建python类型时如果定义了__call__()方法,那么这个类型就是可调用的,比如在这个场景里 print(callable(d))就会输出True。
以下内容参考博客: Python类的__call__()方法
__call__():Python中,只要在创建类型的时候定义了__call__()方法,这个类型就是可调用的。
Python中的所有东西都是对象,其中包括Int/str/func/class这四类,它们都是对象,都是从一个类创建而来的。元类就是创建这些对象的东西,type就是Python的内建元类。
其中,func是可调用的对象,说明在创建它的类型(父类或它本身)的时候,定义了__call__()方法。
>>>callable(lambda:8)
True
>>>def fn():
pass
>>>callable(fn)
True
所以一个类实例也可以成为类似函数这样能直接调用的对象,只要定义的时候有__call__()方法就可以。
>>>class Reader():
def __init__(self,name,nationality):
self.name = name
self.nationality = nationality
def __call__(self):
print('Reader: %s Nationality: %s' % (self.name, self.nationality))
>>>r = Reader('Annie','Chinese')
>>>r()
Reader:Annie Nationality: Chinese
__call__()方法还可以带参数
定义一个可以直接调用类实例的Reader类,并可统计读者数量
>>>class Reader():
count = 0
def __init__(self,name,nationality):
self.name = name
self.nationality = nationality
Reader.count += 1
def __call__(self, behave):
print('Reader: %s' % self.name)
print('Nationality: %s' % self.nationality)
print('%s is being %s.' % (self.name, behave))
print('The total number of readers is %s.' % Reader.count)
>>>a = Reader('Annie','Chinese')
>>>a('Nice')
Reader: Annie
Nationality: Chinese
Annie is being Nice.
The total number of readers is 1.
>>>b = Reader('Adam','American')
>>>b('Silly')
Reader: Adam
Nationality: American
Adam is being Silly.
The total number of readers is 2. #自动增加