标签: walrus-operator

如何使用海象运算符输入提示?

我正在尝试输入提示海象运算符表达式,即

while (var: int := some_func()): ...

我怎样才能做到这一点?

python walrus-operator

17
推荐指数
1
解决办法
2735
查看次数

字典理解中的海象运算符

我想避免在字典理解中对平均值进行双重评估,并且我尝试使用海象运算符:

>>> dic = {"A": [45,58,75], "B": [55,82,80,92], "C": [78,95,90], "D":[98,75]}
>>> q = {x: (mean := (sum(dic[x]) // len(dic[x]))) for x in dic if mean > 65}
Run Code Online (Sandbox Code Playgroud)

但这给了我以下错误:

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    q = {x: (mean := (sum(dic[x]) // len(dic[x]))) for x in dic if mean > 65}
  File "<pyshell#2>", line 1, in <dictcomp>
    q = {x: (mean := (sum(dic[x]) // len(dic[x]))) for x in dic if mean > 65}
  NameError: name …
Run Code Online (Sandbox Code Playgroud)

python dictionary-comprehension python-3.9 walrus-operator

14
推荐指数
1
解决办法
3653
查看次数

为什么不能使用 Python 的 walrus 运算符来设置实例属性?

我刚刚了解到新的 walrus 运算符 ( :=) 不能用于设置实例属性,它应该是无效的语法(引发 a SyntaxError)。

为什么是这样? (你能提供一个提到这个的官方文档的链接吗?)

我查看了PEP 572,找不到是否/在哪里记录了这一点。


研究

这个答案在没有解释或来源的情况下提到了这个限制:

您不能在对象属性上使用 walrus 运算符


示例代码

class Foo:
    def __init__(self):
        self.foo: int = 0

    def bar(self, value: int) -> None:
        self.spam(self.foo := value)  # Invalid syntax

    def baz(self, value: int) -> None:
        self.spam(temp := value)
        self.foo = temp

    def spam(self, value: int) -> None:
        """Do something with value."""
Run Code Online (Sandbox Code Playgroud)

尝试导入Foo结果为SyntaxError

    self.spam(self.foo := value)
              ^
SyntaxError: cannot use assignment expressions with …
Run Code Online (Sandbox Code Playgroud)

python syntax-error python-3.8 walrus-operator

12
推荐指数
2
解决办法
1455
查看次数

为什么“if not a := say_empty()”会引发语法错误?

PEP 572引入了赋值运算符(“海象运算符”)。

以下代码有效并输出empty

def say_empty():
    return ''

if a := say_empty():
    print("not empty")
else:
    print("empty")
Run Code Online (Sandbox Code Playgroud)

我试图否定这个条件:

def say_empty():
    return ''

if not a := say_empty():
    print("empty")
else:
    print("not empty")
Run Code Online (Sandbox Code Playgroud)

这就提出了一个SyntaxError

    if not a := say_empty():
       ^
SyntaxError: cannot use assignment expressions with operator
Run Code Online (Sandbox Code Playgroud)

给定的错误很明显,但是我想知道为什么要实施此限制。

PEP 572 解释了为什么在迭代中使用赋值会出现问题(并引发SyntaxError),但我没有找到任何有关布尔值的信息。

python python-3.x walrus-operator

12
推荐指数
1
解决办法
2235
查看次数

在 if 语句中使用海象运算符不起作用

我有一个简单的函数,应该根据模式或None不匹配的情况输出前缀。尝试做海象似乎不起作用。任何想法?

import re

def get_prefix(name):
    if m := re.match(f'^.+(\d\d)-(\d\d)-(\d\d\d\d)$', name) is not None:
        return m.group(3) + m.group(2) + m.group(1)

get_prefix('abc 10-12-2020')
Run Code Online (Sandbox Code Playgroud)

追溯

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in get_prefix
AttributeError: 'bool' object has no attribute 'group'
Run Code Online (Sandbox Code Playgroud)

python walrus-operator

9
推荐指数
1
解决办法
1万
查看次数

赋值表达式的求值顺序(海象运算符)

我有以下表达:

>>> a = 3
>>> b = 2
>>> a == (a := b)
False
Run Code Online (Sandbox Code Playgroud)

现在,a == 2手术后,正如预期的那样。结果就是我想要的,即a在分配之前与分配的 RHS 进行比较。

颠倒等号运算符的顺序会颠倒结果:

>>> a = 3
>>> b = 2
>>> (a := b) == a
True
Run Code Online (Sandbox Code Playgroud)

PEP-572 相对优先级部分中似乎没有任何与此极端情况直接相关的内容。下一节,更改评估顺序提到评估顺序是从左到右。这就是这里发生的情况吗(存储 的值a,更新它,然后比较与 update a,然后与其新值进行比较)?

这种行为是在哪里定义的,它的可靠性如何?

python python-assignment-expression walrus-operator

8
推荐指数
1
解决办法
670
查看次数

为什么在成员变量上使用海象运算符会引发语法错误?

为什么我不能使用 walrus 运算符:=来分配属性?它在分配给局部变量时起作用:

my_eyes = ["left", "right"]
if saved_eye := my_eyes.index("left"):
    print(saved_eye)

# outputs >>> 0
Run Code Online (Sandbox Code Playgroud)

但如果我尝试分配给对象属性,则会出现语法错误:

class MyEyes:
    def __init__(self):
        self.eyes = ["left", "right"]
        self.saved_eye = None

    def ohyes(self):
        if self.saved_eye := self.eyes.index("left"):
            print(self.saved_eye)

x = MyEyes()
x.ohyes()

# raises 
# >>> if self.saved_eye := self.eyes.index("left"):
# >>> SyntaxError: cannot use assignment expressions with attribute 
Run Code Online (Sandbox Code Playgroud)

我的意思是我可以使用临时局部变量绕过错误,但为什么会发生这种情况?我相信 100% 这是合法的语法。

python python-3.9 walrus-operator

6
推荐指数
1
解决办法
1238
查看次数

一个 If 语句中的两个 Walrus 运算符

是否有在 1 个 if 语句中包含两个海象运算符的正确方法?

if (three:= i%3==0) and (five:= i%5 ==0):
    arr.append("FizzBuzz")
elif three:
    arr.append("Fizz")
elif five:
    arr.append("Buzz")
else:
    arr.append(str(i-1))
Run Code Online (Sandbox Code Playgroud)

该示例适用于threefive将“未定义”。

python python-3.x walrus-operator

6
推荐指数
1
解决办法
1465
查看次数

如何在 f 字符串中解释命名表达式?

我正在尝试在 f 字符串中使用命名表达式:

print(f"{(a:=5 + 6) = }")
Run Code Online (Sandbox Code Playgroud)

返回:

(a:=5 + 6) = 11
Run Code Online (Sandbox Code Playgroud)

但我希望有这样的事情:

a = 11
Run Code Online (Sandbox Code Playgroud)

通过组合海象运算符和 f 字符串是否可能(这样我就不必a在单独的步骤中首先声明变量)?

python string-interpolation python-3.x f-string walrus-operator

5
推荐指数
1
解决办法
1567
查看次数

如何检查在 Python 中使用 Walrus 运算符时是否按下了 Enter 键?

我正在尝试使用 Walrus operator 获取用户的输入:=,但如果用户只输入Enter密钥 as input,则 python 脚本将终止。如何捕获此错误并确保用户不仅按下了Enter键?

这个答案,但它不适用于海象运算符。

这段没有 walrus 运算符的代码将成功检查是否不仅Enter按下了键:

while True:
    answer = input("Please enter something: ")
    if answer == "":
        print("Invalid! Enter key was pressed.")
        continue
    else:
        print("Enter wasn't pressed!")
        # do something
Run Code Online (Sandbox Code Playgroud)

如果用户只按下Enter,则整个脚本将终止。

while answer := input("Please enter something: "):
    # if user pressed only `Enter` script will terminate. following will never run
    if answer == "":
        print("enter was pressed")
    else:
        print("Enter …
Run Code Online (Sandbox Code Playgroud)

python python-3.x walrus-operator

5
推荐指数
1
解决办法
269
查看次数