nick_gabpe Asked:2020-07-13 22:16:11 +0000 UTC2020-07-13 22:16:11 +0000 UTC 2020-07-13 22:16:11 +0000 UTC 为什么 Python 3.8 引入了新的 := 运算符? 772 PEP 572 - 赋值表达式引入了一个新的:=. 他在做什么?它是干什么用的? python 2 个回答 Voted Best Answer jfs 2020-07-15T01:09:22Z2020-07-15T01:09:22Z 可以应用PEP 572: The Walrus Operator的现有(非特别发明)代码(磁盘上的 grep-zero)示例: 复制文件(以及套接字和其他对象的类似代码,您可以从中接收数据而不为空): # copy the rest buf = inputfile.read(bufsize) while buf: outputfile.write(buf) buf = inputfile.read(bufsize) 使用PEP-572可以替换为: # copy the rest while buf := inputfile.read(bufsize): outputfile.write(buf) 当然,现在可以写成: # copy the rest shutil.copyfileobj(inputfile, outputfile, bufsize) shutil.copyfileobj()在无法直接应用的地方复制(请参阅Get an audio file with HTTP GET and then play it in python 3. TTS in python 3?): while True: data = wavfile.readframes(4096) if not data: break output_file.write(data) 使用PEP-572可以替换为: while data := wavfile.readframes(4096): output_file.write(data) 有时它是iter()用两个参数编写的(请参阅Floating point to 16 bit Twos Complement Binary, Python): output_file.writelines(iter(lambda: wavfile.readframes(4096), b'')) 使用正则表达式进行分支,例如,来自Python 3 的代码从互联网广播流中获取歌曲名称: m = re.search(r"StreamTitle='([^']*)';", metadata) if m: title = m.group(1) if title: break # found title 可以替换为: if m := re.search(r"StreamTitle='([^']*)';", metadata) and title := m.group(1): break # found title 列表包含(listcomp),其中某个表达式被多次使用。例如,将对象的公共非特殊属性obj(属性,而不是方法)打印为由 dictcomp 创建的字典: pprint({name: attr for name in dir(obj) if not name.startswith("__") for attr in [getattr(obj, name)] if not callable(attr)}) 这里DRY是使用以下方法实现的:for attr in [getattr(obj, name)]idiom(添加了一个通过一个元素列表的额外嵌套循环)。使用PEP-572,这可以重写为: pprint({name: attr for name in dir(obj) if not name.startswith("__") and not callable(attr := getattr(obj, name))}) 当然,特别是在不需要整个表达式的情况下,可以使用显式循环代替 dictcomp。 另一个 listcomp 示例(请参阅Base RLE encode python): def rle_groupby(text): return ''.join([char if count == 1 else str(count) + char for char, same in groupby(text) for count in [sum(1 for _ in same)]]) 在这里,相同的 DRY 习语与单元素列表一起使用。使用PEP-572,这可以重写为: def rle_groupby(text): return ''.join([char if (count := sum(1 for _ in same)) == 1 else str(count) + char for char, same in groupby(text)]) PEP-572 本身的现有代码和改进示例。 问:为什么不能像 C# 中那样使用普通的 = 运算符? A:为了避免与==C中的和之间if (x == y)if (x = y)的方式混淆,它们做的事情完全不同。 MarianD 2020-07-14T20:39:09Z2020-07-14T20:39:09Z 不需要——这就是所谓的语法糖,它可以让你写的代码更紧凑、更清晰。 这是一个没有语法糖的例子: if len(string) > 100: print(len(string)) # дважды вычисляется len(string) 相同的: if (length := len(string)) > 100: print(length) 另一个例子: age = int(input("Ваш возраст: ")) if age > 18: # age должен быть введен перед if print(age) 可以嚎叫 if (age := int(input("Ваш возраст: "))) > 18: print(age) 注意:C/C++ 程序员从这些语言的第一个版本开始就知道并使用了这一点。在Python中,这可以从 3.8 版本开始。
可以应用PEP 572: The Walrus Operator的现有(非特别发明)代码(磁盘上的 grep-zero)示例:
复制文件(以及套接字和其他对象的类似代码,您可以从中接收数据而不为空):
使用PEP-572可以替换为:
当然,现在可以写成:
shutil.copyfileobj()在无法直接应用的地方复制(请参阅Get an audio file with HTTP GET and then play it in python 3. TTS in python 3?):使用PEP-572可以替换为:
有时它是
iter()用两个参数编写的(请参阅Floating point to 16 bit Twos Complement Binary, Python):使用正则表达式进行分支,例如,来自Python 3 的代码从互联网广播流中获取歌曲名称:
可以替换为:
列表包含(listcomp),其中某个表达式被多次使用。例如,将对象的公共非特殊属性
obj(属性,而不是方法)打印为由 dictcomp 创建的字典:这里DRY是使用以下方法实现的:
for attr in [getattr(obj, name)]idiom(添加了一个通过一个元素列表的额外嵌套循环)。使用PEP-572,这可以重写为:当然,特别是在不需要整个表达式的情况下,可以使用显式循环代替 dictcomp。
另一个 listcomp 示例(请参阅Base RLE encode python):
在这里,相同的 DRY 习语与单元素列表一起使用。使用PEP-572,这可以重写为:
PEP-572 本身的现有代码和改进示例。
A:为了避免与
==C中的和之间if (x == y)if (x = y)的方式混淆,它们做的事情完全不同。不需要——这就是所谓的语法糖,它可以让你写的代码更紧凑、更清晰。
这是一个没有语法糖的例子:
相同的:
另一个例子:
可以嚎叫
注意:C/C++ 程序员从这些语言的第一个版本开始就知道并使用了这一点。在Python中,这可以从 3.8 版本开始。