gpt4 book ai didi

python - for 循环名称列表表达式是否合法?

转载 作者:太空狗 更新时间:2023-10-30 02:27:43 24 4
gpt4 key购买 nike

在 CPython 2.7.10 和 3.4.3 以及 PyPy 2.6.0 (Python 2.7.9) 中,在 for 循环中对名称列表使用表达式(或它们的某些子集)显然是合法的。这是一个典型的 for 循环:

>>> for a in [1]: pass
...
>>> a
1

但您也可以使用对象的属性:

>>> class Obj(object): pass
...
>>> obj = Obj()
>>> for obj.b in [1]: pass
...
>>> obj.b
1

您甚至可以使用表达式中的属性:

>>> for Obj().c in [1]: pass
...

但并不是所有的表达式都有效:

>>> for (True and obj.d) in [1]: pass
...
File "<stdin>", line 1
SyntaxError: can't assign to operator

但只要属性在外面,它们就可以吗?

>>> for (True and obj).e in [1]: pass
...
>>> obj.e
1

或者某些东西是可分配的?

>>> for {}['f'] in [1]: pass
...

我很惊讶这些在 Python 中都是合法的语法。我希望只允许使用名称。这些甚至应该工作吗?这是疏忽吗?这是 PyPy 碰巧也实现的 CPython 的实现细节吗?

最佳答案

Are these even supposed to work?

Is this an oversight?

没有

Is this an implementation detail of CPython that PyPy happens to also implement?

没有


如果可以给它赋值,就可以把它作为for循环中的自由变量。

对于此类问题,值得直接转到 grammar :

for_stmt ::=  "for" target_list "in" expression_list ":" suite
["else" ":" suite]

target_list 只是一堆target:

target_list     ::=  target ("," target)* [","]
target ::= identifier
| "(" target_list ")"
| "[" [target_list] "]"
| attributeref
| subscription
| slicing
| "*" target

如果仔细观察,您会发现您提供的所有工作示例都不是反例。请注意,解析器中的错误并非闻所未闻(even I found one once),因此如果您发现合法的语法异常,请提交一张票——这些错误往往会很快得到修复。

你给出的最有趣的一对是(True and obj.d)(True and obj).d,它们在逻辑上看起来是一样的,但是被解析了不同的是:

>>> ast.dump(ast.parse('(True and obj.d)'), annotate_fields=False)
"Module([Expr(BoolOp(And(), [Name('True', Load()), Attribute(Name('obj', Load()), 'd', Load())]))])"
>>> ast.dump(ast.parse('(True and obj).d'), annotate_fields=False)
"Module([Expr(Attribute(BoolOp(And(), [Name('True', Load()), Name('obj', Load())]), 'd', Load()))])"

注意: (True and obj).dattributeref在语法中。

关于python - for 循环名称列表表达式是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39539606/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com