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

2024-01-22

我尝试使用 walrus 运算符进行多次分配,并在 StackOverflow 上看到了一些问题,例如this https://stackoverflow.com/questions/59226071/how-to-perform-assignment-destructuring-using-the-walrus-operator-in-python它也无法使用海象运算符分配多个变量,我只是想知道成功的多重分配会是什么样子,或者是否不可能。

这样做的目的是添加对检测我的库中所有分配的变量名称的支持mvdef https://github.com/lmmx/mvdef(具体来说,在find_assigned_args https://github.com/lmmx/mvdef/blob/master/mvdef/src/ast_util.py函数在mvdef.src.ast_util模块)。

从跑步开始ast.parse我可以看到:=运算符产生一个ast.NamedExpr节点,这有一个.target属性是一个ast.Name对象,我可以从中获取对象的指定名称.id属性。

如果我必须猜测的话,我会认为如果有可能的话,.target属性将是一个列表ast.Name对象而不是单个ast.Name对象,但是事实上我似乎无法获得这方面的示例,这让我想知道这是否不可能,至少暂时如此(在这种情况下,我可以简化我的代码,而不仅仅是猜测实现应该是什么)。

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

附: - 从查看测试用例Lib/test/test_parser.py中提供的初始提交 https://github.com/python/cpython/commit/8f59ee01be3d83d5513a9a3f654a237d77d80d9a (via https://bugs.python.org/issue35224),似乎没有海象运算符多重赋值的例子,所以我现在假设这是不可能的(但如果我错了,请插话!)

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)")


可迭代的打包和拆包是两者之间的区别之一= and :=,只有前者支持他们。正如发现的PEP-572 https://www.python.org/dev/peps/pep-0572/#differences-between-assignment-expressions-and-assignment-statements:

# 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 walrus := 运算符进行多次赋值? 的相关文章

随机推荐