英文:
Multiple object returns from method not acting as expected
问题
在使用pyautogui
时,我决定创建一个方法,根据我的显示器尺寸来限制光标的位置,因为我之前是随机移动光标。
这是我的第一个尝试:
max_x = 10
max_y = 40
def limitXandY(x_arg, y_arg):
# 预期输出长度为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语句的第一个值作为方法输出元组的第一个值。
我已经找到了一个解决方法,使用括号,但这并不完全满足我,我想理解为什么这个三元运算符会这样行为。
解释是有帮助的!
英文:
While playing around with pyautogui
I decided to make a method to limit the position of my cursor depending on the size of my monitor, since I was moving my cursor randomy.
This is what my first attempt looked like.
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
When running the code I did not get the expected output.
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)
As you can see above, my method returns a tuple of length 3 instead of 2. If the ternary operator goes in the if statement, I get the desired output plus last value of the else statement and if the operator returns in the else statement, I get the first value of the if statement as the first value of the methods output tuple.
I have found a work around using parentheses, but this doesn't really satisfy me and I would like to understand why this ternary operator acts like this.
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 error
Any explanations would be a help!
答案1
得分: 1
以下是要翻译的内容:
你的第一段代码等同于这个:
return x_arg, (y_arg if x_arg < max_x and y_arg < max_y else max_x), max_y
这是一个包含三个元素的元组。
这与解释器首先遇到逗号然后是条件有关。也就是说,它首先决定解释为一个元组,然后找到条件表达式。
英文:
Your first snippet of code is equivalent to this:
return x_arg, (y_arg if x_arg < max_x and y_arg < max_y else max_x), max_y
Which is a tuple of three elements.
This has to do with the fact that the interpreter first reaches the comma than the conditional. That is: it first decides is interpreting a tuple and then finds a conditional expression.
答案2
得分: 1
请注意,以下是您要翻译的文本:
"Any explanations would be a help!
While ternaries have a fairly low precedence, they're still considered an operator and thus binding 'tighter' than tuple literal, much like e.g.
a+b,c+d
is interpreted as
(a + b), (c + d)
not
a + (b, c) + d
When you write
x_arg, y_arg if x_arg < max_x and y_arg < max_y else max_x, max_y
Python will first 'resolve' <, then and, then if/else, and only after that does it resolve the tuples, so the result is:
x_arg, (y_arg if ((x_arg < max_x) and (y_arg < max_y)) else max_x), max_y
You can infer this from the full language grammar, specifically:
ebnf
expressions:
| expression (',' expression )+ [',']
| expression ','
| expression
expression:
| disjunction 'if' disjunction 'else' expression
| disjunction
| lambdef
"
英文:
> Any explanations would be a help!
While ternaries have a fairly low precedence, they're still considered an operator and thus binding "tighter" than tuple literal, much like e.g.
a+b,c+d
is interpreted as
(a + b), (c + d)
not
a + (b, c) + d
When you write
x_arg, y_arg if x_arg < max_x and y_arg < max_y else max_x, max_y
Python will first "resolve" <
, then and
, then if/else
, and only after that does it resolve the tuples, so the result is:
x_arg, (y_arg if ((x_arg < max_x) and (y_arg < max_y)) else max_x), max_y
You can infer this from the full language grammar, specifically:
expressions:
| expression (',' expression )+ [',']
| expression ','
| expression
expression:
| disjunction 'if' disjunction 'else' expression
| disjunction
| lambdef
Here you can see that an expressions
is a comma-separated sequence of expression
, and each expression
can be a ternary (if/else
), therefore the language "resolves" ternaries (the inner structure) first.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论