我正在使用Python for Robot Framework中的可嵌套For循环。我的目标是模仿100%的原始功能,所以如果满足某些条件,我需要能够打破For循环。我的解决方案是使用自定义关键字,在Python代码中评估的方式略有不同:exit_if
。
exit_if
接受一个参数,一个字符串,并返回一个参数进行处理,一个布尔值。我想发送一个像'$var1 == $var2'
这样的字符串(我已经解决了在机器人框架的For循环中创建的自定义变量名称周围需要括号的问题),让exit_if
将字符串计算为它将是任何布尔表达式,如果表达式求值为True
则返回True
,如果表达式求值为False
则返回False
。
一个简单的解决方案是让exit_if
采用三个参数:var1
,operator
和var2
。然后,在switch语句中,根据运算符计算变量。然而,这似乎不必要地笨拙和低效,所以我想找到一个更优雅的解决方案。
谷歌搜索后(可能我的谷歌搜索参数化不正确),我发现没有什么可以做我要求该程序做的事情,所以,鉴于这是一个编码问题,可以使未来的程序员受益,我转向这个网站。如何使用单个参数和no / minimum switch / if语句来实现三参数解决方案的效果?
编辑:我为原帖的简洁而道歉,在提出这个问题的过程中,我被赶出了办公室。 Robot Framework通过以类似框架的语言发送很长的信息单元列表来与我的For循环交互,然后我的代码处理这些单元格并转换为BuiltIn().run_keywords
所需的格式。在Robot Framework中,这种格式看起来像这样(简单版本):
For Loop IN RANGE 0 3 INDEX0
... \\ Log to Console INDEX0
... \\ Run Keyword If INDEX0 == 1 Log to Console one
Robot Framework将其作为一行单元格处理,如下所示(单元格由|分隔:
)For Loop|IN RANGE|0|2|INDEX0|\\|Log to Console|INDEX0|\\|Run Keyword If|INDEX0 == 1|Log to Console|one
我的代码将这些单元格转换为字符串列表。
['For Loop','IN RANGE','0','2','INDEX0','\\','Log to Console','INDEX0','\\','Run Keyword If','INDEX0 == 1','Log to Console','one']
然后,用于格式化它的代码使用BuiltIn().run_keywords()
的每个循环迭代。因此,在迭代2(INDEX0 = 1):
kwords = ['Log to Console','1','AND','Run Keyword If','1 == 1','Log to Console','one']
BuiltIn().run_keywords(*kwords)
该系统太受限于Run Keywords
的内置功能,我创建了一个我可以控制的镜像版本。它的功能与Run Keywords
相同,但由self._run_keywords(*kwords)
调用。
现在看来,该代码将无法运行。我正在尝试创建将处理1 == 1
并将其传递给某个关键字的代码。鉴于我目前的目标是允许用户在循环中指定断点,我创建了一个名为exit_if
的函数。 exit_if
将(最终)以字符串的形式接收一个参数输入(如上所述,但不一定使用相同的语法),确定条件是否正确退出for循环,并退出for环。我希望它返回一个布尔值用于验证目的,因为我不完全确定exit_if
如何与文件的其余部分进行交互。
我已经知道一种非常笨重的方法。获取输入(1 == 1
),使用字符串解析来查找运算符和变量,使用switch语句来决定要进行的比较,进行比较,并(可能)将值返回到循环的其余部分,以便它可以阻止循环。
感谢Kindall,我现在可以通过字典和operator
更轻松地完成此操作,但我希望能够提供更优雅的解决方案:
def exit_if(argument_string):
if argument_string:
return True
else:
return False
显然,为if
语句提供现有字符串总是会产生True
,但我希望能够将字符串转换为某些内容或将函数应用于它以将其转换为布尔值声明。如果这是不可能的,我需要采取笨重的方式,那很好。速度和美丽不是要求,但值得问。
答案 0 :(得分:1)
使用operator
模块和字典。
import operator
ops = {"==": operator.eq,
"!=": operator.ne,
"<": operator.lt,
"<=": operator.le,
">": operator.gt,
">=": operator.ge}
def compare(a, op, b):
return ops[op](a, b)
assert compare(3, "<", 4)
查看你的变量名并传入它们的值,我会留给你。
答案 1 :(得分:0)
您可以使用正则表达式来解决此问题。
import re
varSet = {'var1' : 1, 'var2' : 2 } #Dictionary for your variables
def exit_if(stringPassed):
#(.*) - any character and its occurence
pattern = re.compile(r'(.*) (.*) (.*)')
#Looks for the matches, result.group(0) shows the result
result = pattern.match(stringPassed)
firstVariable = varSet[result.group(1)] #'var1'
operatorUsed = result.group(2) #'=='
secondVariable = varSet[result.group(3)] #'var2'
if operatorUsed == '==':
return firstVariable == secondVariable
elif operatorUsed == '!=':
return firstVariable != secondVariable
elif operatorUsed == '<':
return firstVariable < secondVariable
elif operatorUsed == '<=':
return firstVariable <= secondVariable
elif operatorUsed == '>':
return firstVariable > secondVariable
elif operatorUSed == '>=':
return firstVariable >= secondVariable
else:
print ('Some kind of error')
#Given that the pattern is always '$var1 == $var2'
print exit_if('var1 == var2') #prints False
print exit_if('var1 < var2') #prints True
有关re模块的更多信息: