无法在赋值表达式中设置字段值 [英] Cannot set field value in assignment expression

查看:214
本文介绍了无法在赋值表达式中设置字段值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

With Python 3.8 Assignment Expressions have been introduced, allowing to assign values in conditionals and lambdas as such:

if x := True:
    print(x)

但是,这似乎并没有扩展到属性分配,而是尝试执行类似的操作

However it appears this does not extends to attribute assignment, as trying to do something like this

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 

真的只能更新作业陈述中的属性(而不是作业表达式)吗?如果可以,为什么要使用此限制?

Is it really only possible to update attribute in assignment statements (as opposed to assignment expressions) and if yes why this limitation?

推荐答案

从pep开始:

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

最重要的是,由于:=是表达式,因此可以在语句非法的上下文中使用,包括lambda函数和理解.

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:

  • 不支持单个NAME以外的其他分配目标:
  • Single assignment targets other than a single NAME are not supported:

# No equivalent
a[i] = x
self.rest = []

似乎是为了避免太复杂的事情而出现的(这表明它可能应该在某处变成完整的语句).另外,这已经可以通过setattr:

Seems like it was just made to avoid things that are too complicated (Which is a sign that it should probably be turned into a full statement somewhere). Also, this can already be achieved with 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 decorator)
def set_member(obj, member_name, new_value):
    setattr(obj, member_name, new_value)
    return getattr(obj, member_name)

这篇关于无法在赋值表达式中设置字段值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆