在玩
pyautogui
时,我决定根据显示器的大小来限制光标的位置,因为我是随机移动光标的。
这是我第一次尝试的样子。
max_x = 10
max_y = 40
def limitXandY(x_arg, y_arg):
# expected to outputs a tuple of integers with length 2
return x_arg, y_arg if x_arg < max_x and y_arg < max_y else max_x, max_y
运行代码时,我没有得到预期的输出。
print(limitXandY(5, 19)) # (5, 19, 40) => (x_arg, y_arg, max_y)
x, y = limitXandY(5, 19) # ValueError: too many values to unpack (expected 2)
print(limitXandY(50, 100)) # (50, 10, 40) => (x_arg, max_x, max_y)
x, y = limitXandY(50, 100) # ValueError: too many values to unpack (expected 2)
正如您在上面看到的,我的方法返回一个长度为 3 而不是 2 的元组。如果三元运算符进入 if 语句,我得到所需的输出加上 else 语句的最后一个值,如果运算符在 else 语句中返回,我得到 if 语句的第一个值作为方法输出元组的第一个值。
我找到了使用括号的解决方法,但这并不能真正让我满意,我想了解为什么这个三元运算符会这样。
def correctedLimitXandY(x_arg, y_arg):
# expected to output a tuple of tuple with length 1
# inner tuple should containt integers of length 2
return (x_arg, y_arg) if x_arg < max_x and y_arg < max_y else (max_x, max_y)
print(correctedLimitXandY(5, 19)) # (5, 19) => (x_arg, y_arg)
x, y = correctedLimitXandY(5, 19) # no error
print(correctedLimitXandY(50, 100)) # (10, 40) => (max_x, max_y)
x, y = correctedLimitXandY(50, 100) # no erro
任何解释都会有帮助!
任何解释都会有帮助!
虽然三元组的优先级相当低,但它们仍然被认为是运算符,因此比元组文字绑定“更紧密”,就像例如
a+b,c+d
被解释为
(a + b), (c + d)
不
a + (b, c) + d
写作时
x_arg, y_arg if x_arg < max_x and y_arg < max_y else max_x, max_y
Python 将首先“解析”
<
,然后是and
,然后是if/else
,然后才解析元组,所以结果是:
x_arg, (y_arg if ((x_arg < max_x) and (y_arg < max_y)) else max_x), max_y
你可以从完整的语言语法中推断出这一点,具体来说:
expressions:
| expression (',' expression )+ [',']
| expression ','
| expression
expression:
| disjunction 'if' disjunction 'else' expression
| disjunction
| lambdef
在这里你可以看到一个
expressions
是一个逗号分隔的expression
序列,每个expression
可以是一个三元(if/else
),因此语言首先“解析”三元(内部结构)。
您的第一段代码相当于:
return x_arg, (y_arg if x_arg < max_x and y_arg < max_y else max_x), max_y
这是三个元素的元组。
这与解释器首先到达逗号而不是条件句有关。即:它首先判断是在解释一个元组,然后再找到一个条件表达式。