首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过walrus :=运算符进行多个赋值?

通过walrus :=运算符进行多个赋值?
EN

Stack Overflow用户
提问于 2020-01-03 00:59:30
回答 2查看 1.9K关注 0票数 4

我曾尝试使用海象运算符进行多个赋值,并在StackOverflow上看到了this等问题,这些问题也无法使用海象运算符为多个变量赋值,我只是想知道成功的多重赋值是什么样子,或者它是否不可能。

这样做的目的是添加对在我的库mvdef中(特别是在mvdef.src.ast_util模块中的find_assigned_args函数中)检测所有分配的变量名的支持。

通过运行ast.parse,我可以看到:=操作符生成了一个ast.NamedExpr节点,该节点具有一个.target属性,该属性是一个ast.Name对象,我可以从该对象的.id属性中获得分配的名称。

如果非要我猜的话,我会假设如果有可能的话,.target属性应该是一组ast.Name对象,而不是单个ast.Name对象,然而,我似乎不能得到一个这样的例子,这让我怀疑这是否是不可能的,至少目前是这样(在这种情况下,我可以简化我的代码,而不仅仅是猜测一个实现应该是什么)。

如果有人知道该查看Python源代码的哪个特定部分来告诉我这是否可能,那将非常有帮助,谢谢!

附注-从initial commit (via)提供的Lib/test/test_parser.py中的测试用例来看,似乎没有使用海象操作符进行多个赋值的示例,所以我现在假设这是不可能的(但如果我错了,请插话!)

代码语言:javascript
复制
def test_named_expressions(self):
    self.check_suite("(a := 1)")
    self.check_suite("(a := a)")
    self.check_suite("if (match := pattern.search(data)) is None: pass")
    self.check_suite("[y := f(x), y**2, y**3]")
    self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
    self.check_suite("(y := f(x))")
    self.check_suite("y0 = (y1 := f(x))")
    self.check_suite("foo(x=(y := f(x)))")
    self.check_suite("def foo(answer=(p := 42)): pass")
    self.check_suite("def foo(answer: (p := 42) = 5): pass")
    self.check_suite("lambda: (x := 1)")
    self.check_suite("(x := lambda: 1)")
    self.check_suite("(x := lambda: (y := 1))")  # not in PEP
    self.check_suite("lambda line: (m := re.match(pattern, line)) and m.group(1)")
    self.check_suite("x = (y := 0)")
    self.check_suite("(z:=(y:=(x:=0)))")
    self.check_suite("(info := (name, phone, *rest))")
    self.check_suite("(x:=1,2)")
    self.check_suite("(total := total + tax)")
    self.check_suite("len(lines := f.readlines())")
    self.check_suite("foo(x := 3, cat='vector')")
    self.check_suite("foo(cat=(category := 'vector'))")
    self.check_suite("if any(len(longline := l) >= 100 for l in lines): print(longline)")
    self.check_suite(
        "if env_base := os.environ.get('PYTHONUSERBASE', None): return env_base"
    )
    self.check_suite(
        "if self._is_special and (ans := self._check_nans(context=context)): return ans"
    )
    self.check_suite("foo(b := 2, a=1)")
    self.check_suite("foo(b := 2, a=1)")
    self.check_suite("foo((b := 2), a=1)")
    self.check_suite("foo(c=(b := 2), a=1)")
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-03 02:19:22

可迭代打包和解包是=:=之间的一个区别,只有前者支持它们。在PEP-572中可以找到

代码语言:javascript
复制
# Equivalent needs extra parentheses
loc = x, y  # Use (loc := (x, y))
info = name, phone, *rest  # Use (info := (name, phone, *rest))

# No equivalent
px, py, pz = position
name, phone, email, *other_info = contact
票数 6
EN

Stack Overflow用户

发布于 2021-10-19 19:22:00

简而言之,您不能使用walrus -- :=进行多次赋值,但在我看来,这并不是一个显著的缺点,因为有一种方法可以绕过它。

我们总是可以用一个函数包装返回多个值的函数,该函数将返回值的其余部分作为输入参数。

考虑以下示例:

代码语言:javascript
复制
if not (userNameCapture := icm.subProc_bashOut(
        f"""grep Username: {plonePasswdFile} | cut -d ":" -f 2""",
        outcome=cmndOutcome,)): return icm.EH_badOutcome(cmndOutcome)

在这里,我将stdout作为主要返回值,并在outcome中获取stderr。

一切都很好,我们最终得到了海象和多重分配的好处。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59567172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档