RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 854267
Accepted
nick_gabpe
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 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. 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)的方式混淆,它们做的事情完全不同。

    • 34
  2. 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 版本开始。

    • 14

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5