无法在赋值表达式中设置字段值

Mal*_*dus 9 python syntax attributes python-3.8

在 Python 3.8 中引入了赋值表达式,允许在条件和 lambda 表达式中赋值,如下所示:

if x := True:
    print(x)

Run Code Online (Sandbox Code Playgroud)

然而,这似乎并没有扩展到属性分配,因为试图做这样的事情

from typing import NamedTuple 

class Test(NamedTuple): 
    field : bool

test = Test(field=False) 

if test.field := True: 
    print(test.field)
Run Code Online (Sandbox Code Playgroud)

会导致以下错误:

SyntaxError: cannot use named assignment with attribute 
Run Code Online (Sandbox Code Playgroud)

是否真的只能更新赋值语句中的属性(而不是赋值表达式),如果是,为什么会有这个限制?

Art*_*yer 13

来自pep:

赋值表达式和赋值语句的区别

最重要的是,由于:=是一个表达式,它可以用于语句不合法的上下文中,包括 lambda 函数和推导式。

相反,赋值表达式不支持赋值语句中的高级功能:

似乎只是为了避免过于复杂的事情(这表明它可能应该在某处变成完整的陈述)。此外,这已经可以通过以下方式实现setattr

# This is not that readable, but has the same semantics as what you asked for
if (setattr(test, 'field', new_test_field := ...), new_test_field)[1]:
    ...

# More readable with a helper function
def set_member(obj, member_name, new_value):
    setattr(obj, member_name, new_value)
    return new_value

if set_member(test, 'field', ...):
    ...


# But you might have wanted to check the new `test.field`
# instead of what you assigned it (In case it was a getter/setter descriptor)
def set_member(obj, member_name, new_value):
    setattr(obj, member_name, new_value)
    return getattr(obj, member_name)
Run Code Online (Sandbox Code Playgroud)

  • 很抱歉没有足够彻底地阅读激励措施。赋值表达式的限制是不幸的,但我猜 `setattr` 紧随其后。谢谢你! (2认同)