无法在赋值表达式中设置字段值
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)
引入了 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)