python-3.8.0 新特性之賦值表達式

python-3.8.0 新特性之賦值表達式python

賦值表達式的語法是這樣的「 name := expression 」,形式上看和賦值語句 「 = 」 差很少,就做用上來看也雷同。也就是說 「:=」 不是必不可少的,它只是一個錦上添花的新語法。sql

 

一、例子express

假設咱們要對列表中的元素個數進行判斷,當其大於 3 個的時候打印出提示信息,用老的語法咱們能夠這樣寫。socket

#!/usr/bin/env python3

if __name__ == "__main__":
    ls = [1,2,3,4,5]
    if len(ls) > 3: # 第一次計算 len(ls)
        print(f"ls is too long ({len(ls)} elements,expected < 3)") # 第二次計算 len(ls)

能夠看到在上面的代碼中咱們重複的計算了 len(ls) ,雖然 python 內部對於 len(ls) 會有一些優化操做,可是咱們並不想重複本身,要優化辦法也是有的把 len(ls) 前置一下就行。優化

#!/usr/bin/env python3

if __name__ == "__main__":
    ls = [1,2,3,4,5]
    n = len(ls) # 第一次計算 len(ls)
    if n > 3:
        print(f"ls is too long ({n} elements,expected < 3)") # 直接使用變量 n ,省去了一次計算過程

 

二、用新特性重寫spa

感受說什麼都是在注水,直接上代碼code

#!/usr/bin/env python3

if __name__ == "__main__":
    ls = [1,2,3,4,5]
    if (n:=len(ls)) > 3: # 只要計算一次
        print(f"ls is too long ({n} elements,expected < 3)") # 直接使用賦值表達式中的 n 一樣也省去了一次計算

 

三、兩種寫法的比較對象

優劣分析blog

# 寫法 一 
#!/usr/bin/env python3

if __name__ == "__main__":
    ls = [1,2,3,4,5]
    n = len(ls)
    if n > 3:
        print(f"ls is too long ({n} elements,expected < 3)")

# 寫法 二
#!/usr/bin/env python3

if __name__ == "__main__":
    ls = [1,2,3,4,5]
    if (n:=len(ls)) > 3:
        print(f"ls is too long ({n} elements,expected < 3)")

 

python 這門語言最好的一個地方就在於它的一致性,無論是專家仍是初生牛犢,只要一看到他人的代碼大體就能夠猜到他接下來想作什麼,長此以往同一類型的問題就有了最 pythonic 的寫法了。element

第一種寫法當咱們看到 「n = len(ls)」 時即不能回答做者想要用 n 來作什麼?也不能回答「後面的代碼必定會用到 n 嗎?」這樣的問題,要解答這些問題都要要求咱們往下看代碼。

第二種寫法當咱們看到 「if (n:=len(ls)) > 3:」 一來咱們直接能夠看出這個 if 依賴於 n 的值,二來後面的代碼也很是有可能會用到 n ,若是不用的話直接寫成 「if len(ls) > 3:」 不就好了嗎? 

總結:把正確的屬性用在正確的地方是能夠提升代碼可讀性的。

 

四、:= 與 = 的關係

看官方的意思 「:=」 是做爲 「=」 的一個補充而存在的,並非想用 「:=」 替換掉 「=」,下面看一下它兩是互補的一個例子

#!/usr/bin/env python3

if __name__ == "__main__":
    x = 5
    print(f"x = {x}")

    y := 5 # SyntaxError: invalid syntax
    print(f"y = {y}")
    #這樣的寫法是會報語法錯誤的,我以爲這裏體現了官方的兩個重要的思想
    # 一、能夠用 "=" 解決的事就不要用 ":=" 防止引發混亂
    # 二、對於一個給定的問題最 pythonic 的寫法一般只有一種

    (z := 5)
    print(f"z = {z}")

 

五、新寫法帶來的最佳實踐

# 一 簡化 os.fork 
if pid := os.fork():
    # Parent code
else:
    # Child code

# 二 直接到把 socket 對象的 read buffer 讀完爲止
while data := sock.recv(8192):
    print("Received data:", data)

 

轉自

https://www.sqlpy.com/blogs/books/2/chapters/10/articles/51

相關文章
相關標籤/搜索