折腾:
【未解决】安卓游戏暗黑觉醒自动化:进入首页后就是首充充值弹框
期间,对于之前函数:
utils/common_utils.py
def multipleRetry(functionInfoDict, maxRetryNum=5, sleepInterval=0.1, isShowErrWhenFail=True): """ do something, retry mutiple time if fail Args: functionInfoDict (dict): function info dict contain functionCallback and [optional] functionParaDict maxRetryNum (int): max retry number sleepInterval (float): sleep time of each interval when fail isShowErrWhenFail (bool): show error when fail if true Returns: bool Raises: """ doSuccess = False functionCallback = functionInfoDict["functionCallback"] functionParaDict = functionInfoDict.get("functionParaDict", None) curRetryNum = maxRetryNum while curRetryNum > 0: if functionParaDict: doSuccess = functionCallback(**functionParaDict) else: doSuccess = functionCallback() if doSuccess: break time.sleep(sleepInterval) curRetryNum -= 1 if not doSuccess: if isShowErrWhenFail: functionName = str(functionCallback) # '<bound method DevicesMethods.switchToAppStoreSearchTab of <src.AppCrawler.AppCrawler object at 0x1053abe80>>' logging.error("Still fail after %d retry for %s", maxRetryNum, functionName) return doSuccess
具体调用举例:
isGotoPay = CommonUtils.multipleRetry({"functionCallback": self.isGotoPayPopupPage})
有个缺点:
传入的函数,返回值必须是:单个的bool变量
而不支持:返回多个值的情况
希望:增加支持传入函数返回值是tuple或别的类型的变量的情况
至少此处是tuple,三个值,则第一个值要是bool
如果支持了这种返回多个值的tuple类型,最好还要:增加把完整的返回值返回给调用者
if functionParaDict: # doSuccess = functionCallback(**functionParaDict) respValue = functionCallback(**functionParaDict) else: # doSuccess = functionCallback() respValue = functionCallback() doSuccess = False if isinstance(respValue, bool): doSuccess = bool(respValue) elif isinstance(respValue, tuple): doSuccess = respValue first value
期间又遇到:对于tuple,不知道具体几个值,希望获取第一个值
如何写?
python get first element of tuple
好像就是支持 someTuple[0] 即可获取第一个值?
Tuples can be indexed just like lists.
就是的,可以像list一样去索引tuple
就像代码:
finalReturnValue = None doSuccess = False if isinstance(respValue, bool): doSuccess = bool(respValue) elif isinstance(respValue, tuple): doSuccess = bool(respValue[0]) elif isinstance(respValue, list): doSuccess = bool(respValue[0]) else: Exception("multipleRetry: Not support type of return value: %s" % respValue) if doSuccess: if isRespFullRetValue: finalReturnValue = respValue else: finalReturnValue = doSuccess break
去调试看看
调用:
def isGotoPayPopupPage_multipleRetry(self, isRespFullInfo=False): """鉴于 暗黑觉醒 的 首充弹框 的检测很不稳定,所以 增加此函数 多次尝试 以确保 当是首充页面时,的确能稳定的检测出的确是""" respBoolOrTuple = CommonUtils.multipleRetry( { "functionCallback": self.isGotoPayPopupPage, "functionParaDict": { "isRespLocation": isRespFullInfo, }, "isRespFullRetValue": isRespFullInfo, } ) return respBoolOrTuple
然后根据此处的isRespFullInfo决定是:
返回单个bool,还会返回完整信息tuple(带坐标位置信息)
其调用:
isGotoPay = self.isGotoPayPopupPage_multipleRetry()
发现参数错误,调整为:
def isGotoPayPopupPage_multipleRetry(self, isRespLocation=False): """鉴于 暗黑觉醒 的 首充弹框 的检测很不稳定,所以 增加此函数 多次尝试 以确保 当是首充页面时,的确能稳定的检测出的确是""" respBoolOrTuple = CommonUtils.multipleRetry( { "functionCallback": self.isGotoPayPopupPage, "functionParaDict": { "isRespLocation": isRespLocation, }, "isRespFullRetValue": isRespLocation, } ) return respBoolOrTuple isGotoPay, matchResult, imgPath = self.isGotoPayPopupPage_multipleRetry(isRespLocation=True)
去调试看看
终于调试到:传入True的情况了
结果调用写错了,改为:
respBoolOrTuple = CommonUtils.multipleRetry( functionInfoDict = { "functionCallback": self.isGotoPayPopupPage, "functionParaDict": { "isRespLocation": isRespLocation, }, }, isRespFullRetValue = isRespLocation, )
再去调试
也支持返回多个值的tuple类型了:
不过返回值要改:
# return doSuccess return finalReturnValue
即可。
【总结】
此处最终代码:
def multipleRetry(functionInfoDict, maxRetryNum=5, sleepInterval=0.1, isShowErrWhenFail=True, isRespFullRetValue=False): """do something, retry if single call failed, retry mutiple time until max retry number Args: functionInfoDict (dict): function info dict contain functionCallback and [optional] functionParaDict maxRetryNum (int): max retry number sleepInterval (float): sleep time (seconds) of each interval when fail isShowErrWhenFail (bool): show error when fail if true isRespFullRetValue (bool): whether return full return value of function call Returns: isRespFullRetValue=False: bool isRespFullRetValue=True: bool / tuple/list/... Raises: """ finalReturnValue = None doSuccess = False functionCallback = functionInfoDict["functionCallback"] functionParaDict = functionInfoDict.get("functionParaDict", None) curRetryNum = maxRetryNum while curRetryNum > 0: if functionParaDict: # doSuccess = functionCallback(**functionParaDict) respValue = functionCallback(**functionParaDict) else: # doSuccess = functionCallback() respValue = functionCallback() doSuccess = False if isinstance(respValue, bool): doSuccess = bool(respValue) elif isinstance(respValue, tuple): doSuccess = bool(respValue[0]) elif isinstance(respValue, list): doSuccess = bool(respValue[0]) else: Exception("multipleRetry: Not support type of return value: %s" % respValue) if doSuccess: if isRespFullRetValue: finalReturnValue = respValue else: finalReturnValue = doSuccess break time.sleep(sleepInterval) curRetryNum -= 1 if not doSuccess: if isShowErrWhenFail: functionName = str(functionCallback) # '<bound method DevicesMethods.switchToAppStoreSearchTab of <src.AppCrawler.AppCrawler object at 0x1053abe80>>' logging.error("Still fail after %d retry for %s", maxRetryNum, functionName) # return doSuccess return finalReturnValue
调用:
def isGotoPayPopupPage_multipleRetry(self, isRespLocation=False): """鉴于 暗黑觉醒 的 首充弹框 的检测很不稳定,所以 增加此函数 多次尝试 以确保 当是首充页面时,的确能稳定的检测出的确是""" respBoolOrTuple = CommonUtils.multipleRetry( functionInfoDict = { "functionCallback": self.isGotoPayPopupPage, "functionParaDict": { "isRespLocation": isRespLocation, }, }, isRespFullRetValue = isRespLocation, ) return respBoolOrTuple
其中此处的:isRespLocation可能是True,即:
respBoolOrTuple = CommonUtils.multipleRetry( functionInfoDict = { "functionCallback": self.isGotoPayPopupPage, "functionParaDict": { "isRespLocation": True, }, }, isRespFullRetValue = True, )
或False:
respBoolOrTuple = CommonUtils.multipleRetry( functionInfoDict = { "functionCallback": self.isGotoPayPopupPage, "functionParaDict": { "isRespLocation": False, }, }, isRespFullRetValue = False, )
=
respBoolOrTuple = CommonUtils.multipleRetry( functionInfoDict = { "functionCallback": self.isGotoPayPopupPage, "functionParaDict": { "isRespLocation": False, }, },