Python元组赋值和签入条件语句
因此,我无意中发现了python中元组的一种特殊行为,我想知道这种行为的发生是否有特殊的原因 虽然我们完全能够将元组分配给变量而不需要 明确地将其括在括号中:Python元组赋值和签入条件语句,python,python-2.7,if-statement,tuples,Python,Python 2.7,If Statement,Tuples,因此,我无意中发现了python中元组的一种特殊行为,我想知道这种行为的发生是否有特殊的原因 虽然我们完全能够将元组分配给变量而不需要 明确地将其括在括号中: >>> foo_bar_tuple = "foo","bar" >>> >>> print foo_bar_tuple == "foo","bar" False bar >>> if foo_bar_tuple == "foo","bar": pass Synt
>>> foo_bar_tuple = "foo","bar"
>>>
>>> print foo_bar_tuple == "foo","bar"
False bar
>>> if foo_bar_tuple == "foo","bar": pass
SyntaxError: invalid syntax
>>>
>>> print foo_bar_tuple == ("foo","bar")
True
>>>
>>> if foo_bar_tuple == ("foo","bar"): pass
>>>
我们无法打印或签入包含变量的条件if语句
前一种方式的元组(无需明确键入括号):
有人知道为什么吗?
提前谢谢,虽然我没有发现任何类似的话题,但如果你认为这是一个可能的问题,请通知我。
干杯
Alex这是因为逗号分隔的表达式在整个逗号分隔元组(在Python语法术语中是“表达式列表”)之前进行计算。因此,当您执行
foo\u bar\u tuple==“foo”,“bar”
,这被解释为(foo\u bar\u tuple==“foo”),“bar”
。中描述了此行为
如果您自己编写这样一个表达式,您可以看到:
>>> 1, 2 == 1, 2 # interpreted as "1, (2==1), 2"
(1, False, 2)
unparenthesized元组的语法错误是因为unparenthesized元组在Python语法中不是“原子”,这意味着它作为if
条件的唯一内容无效。(您可以通过四处追踪来验证这一点。)
你会看到比较出现在表达式之前,而表达式实际上排在最后
in, not in, is, is not, Comparisons, including membership tests
<, <=, >, >=, <>, !=, == and identity tests
...
(expressions...), [expressions...], Binding or tuple display, list display,
{key: value...}, `expressions...` dictionary display, string conversion
in,notin,is,is,not,比较,包括成员资格测试
=, !=, == 和身份测试
...
(表达式…,[表达式…],绑定或元组显示,列表显示,
{key:value…},`expressions…`字典显示,字符串转换
考虑一个示例,如果1==1,2:
会导致语法错误,如下所示:
使用if stmt:'if'test':'suite('elif'test':'suite)*['else':'suite]
,我们可以移动if
关键字并开始解析1==1,2:
对于测试
规则,只有第一个产品匹配:
test: or_test ['if' or_test 'else' test] | lambdef
然后我们得到:
or_test: and_test ('or' and_test)*
然后进入和_test
:
and_test: not_test ('and' not_test)*
现在我们只需进入not_test
:
not_test: 'not' not_test | comparison
注意,我们的输入是1==1,2:
,因此第一个产品不匹配,我们检查另一个:(1)
继续退出(我们只使用第一个非端子,因为零或多个星形需要一个输入中根本没有的端子):
并移动NUMBER
(1
在我们的输入中)并减少。现在我们回到(1),输入==1,2:
进行解析<代码>=
匹配comp\u op
:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
comp_op:“|”=='|'>='|'>在赋值中使用逗号时,实际上是创建元组的东西,而不是圆括号。但是,eq运算符是一个只接受单个参数的函数,当您传递由逗号分隔的值时,它将其视为传递arg
,而不是传递元组'foo','bar'
。parens中的包装强制元组赋值运算符在计算arg
之前发生,因此它的行为与预期一致。换句话说,如果您认为foo\u bar\u tuple=='foo','bar'
实际上是foo\u bar\u tuple.\uu eq\uuuu('foo','bar')
,你可以立即看到为什么你需要包装在帕伦斯使其正常工作!谢谢你们的回答,伙计们@阿鲁伊斯丹特:你所说的foo\u bar\u tuple=='foo',bar'
等同于foo\u bar\u tuple.\uu eq\uu('foo',bar')
是不正确的。比较只发生在'foo'
字符串(foo\u bar\u元组.\uuuu eq\uuuu('foo')
,它是False
)和'bar'
作为一个单独的表达式保留。对!好的,谢谢你的朋友!我会接受的,只要它能让我:)干杯
comparison: expr (comp_op expr)*
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_comp] ')' |
'[' [testlist_comp] ']' |
'{' [dictorsetmaker] '}' |
NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'