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

Cannot set field value in assignment expression

引入了 Python 3.8 Assignment Expressions,允许在条件和 lambda 中赋值:

if x := True:
    print(x)

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

from typing import NamedTuple 

class Test(NamedTuple): 
    field : bool

test = Test(field=False) 

if test.field := True: 
    print(test.field)

会导致以下错误:

SyntaxError: cannot use named assignment with attribute 

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

来自鼓舞人心:

Differences between assignment expressions and assignment statements

Most importantly, since := is an expression, it can be used in contexts where statements are illegal, including lambda functions and comprehensions.

Conversely, assignment expressions don't support the advanced features found in assignment statements:

  • Single assignment targets other than a single NAME are not supported:
    # No equivalent
    a[i] = x
    self.rest = []
    

似乎只是为了避免过于复杂的事情而制作的(这表明它可能应该在某处变成完整的陈述)。此外,这已经可以通过 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)