浅析PEP572:海象运算符

  

现在已经是Python 3.8的最后一个alpha版本,接着就是本月底要发布的的3.8.0β1了。按规定,3.8已经不会再添加(修改)功能了,之前非常有争议的PEP 572的实现已经算是很固定了,我们这篇文章就来先尝个鲜。看看这个新的赋值表达式语法怎么用,何时用。

  

  

PEP572的标题是“赋值表达式”,也就是“赋值表达式”,也叫做“命名表达式”,不过它现在被广泛的别名是“海象运算符”(海象算子)。因为:=很像海象“眼睛小,长着两枚长长的牙”这个特点^ _ ^ .

  

  

我们不详细介绍PEP的内容,直接说应用场景。我觉得它主要可以用在2个地方

  

  

这个小标题想了很久,没找到更合适能表达的。不过相信通过2个例子相信大家就能理解了。

  

首先是一个正则匹配的例子:

        模式=re.compile (“s”)   数据=' https://www.yisu.com/zixun/ss '   如果pattern.match(数据):   print (pattern.match(数据).group (0))      

如果能匹配到条件,匹配对象才会有组织方法。但是这样写虽然节省到一行代码却让执行变慢了,因为重复地执行了2次re.match(数据),正确的写法是:

        匹配=pattern.match(数据)   如果匹配:   打印(match.group (0))      

代码也就只能写成这样了,但如果使用赋值表达式:

        如果(匹配:=pattern.match(数据))不是没有:   打印(match.group (0))      

本来如果这种控制结构语句只是求值表达式,看结果是不是符合条件。而在这里,它做了3件事:

  
      <李>对表达式pattern.match(数据)求值   <李>把值的结果赋值给匹配   <李>把比赛作为如果的条件,判断它的值是不是没有李   
  

我对它的理解是:求值过程中也赋值了新的中间变量,这个(些)中间变量(如这里的比赛)可以在代码块中被继续使用。

  

再看一个文件读取的例子:

        而1:   行=fp.readline ()   如果不行:   打破   打印(线)      

现在可以直接写成:

        而(:=fp.readline ()):   打印(线)      

这可以说是一种代码风格的改进了。

  

  

列表解析性能好,而且非常神谕的,但是它应用场景有限,我们看个例子:

        结果=[]   x的数据:   结果=f (x)   如果结果:   results.append(结果)      

这是一个日常开发里面比较常见的结构。现在是不能用列表解析的,不信的话下面的方案:

        结果=[   f (x)的x数据   如果f (x)   )      

这个是错误的,每次循环执行了2次f函数。现在用赋值表达式可以写成:

        结果=[   x y的数据   如果(y=f (x)):   )      

可以用列表解析了!

  

再看一个PEP提的例子:

        东西=[[y=f (x), x/y) x范围(5))      

其实又回到了赋值给中间变量这个点,每一项包含了y,以及要用y才能获得结果的x/y。

  

上面说的就是海象运算符能实现的目的了~

  

Golang里面的:=

  

:=并不是Python首创的,Golang里面有一个短变量声明(短变量声明)语法:

     //ShortVarDecl=IdentifierList”:=" ExpressionList。   i, j:=0, 10   f:=func () int{返回7}      函数f (n int) (res int,犯错错误){   如果_,犯错:=f (n - 1);犯错!=nil {   返回   }   返回   }   之前      

:=的作用是替代var定义,声明时不需要指定类型。同时由于语言设计,和Python的赋值表达式一样,如上面的例子,f (n - 1)的第二个返回值犯错可以被后面的犯错!=nil使用,用来判断条件是否成立,我非常喜欢!

  

  

在之前我曾经在知乎回答过“如何看待PEP 572 ?“这个问题,当时我这么说:

  

这个PEP有明确的推荐的用例,在正确的地方使用,而不是滥用,当然不喜欢的可以不用,用旧的形式。我语言提供了更多特性和选择的机会,但控制权是开发者手里的,就像元类,描述符,dataclass甚至装饰器等等都是有适用场景的。
  

  

有人觉得它不符合Python之禅,其实我个人感觉挺好的呀。现在PEP 572的实现已经合并到Python3.8,试用下来非常赞。

浅析PEP572:海象运算符