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


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

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

 

1、例子

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

#!/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 ,省去了一次計算過程

 

2、用新特性重寫

感覺說什么都是在注水,直接上代碼

#!/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 同樣也省去了一次計算

 

3、兩種寫法的比較

優劣分析

# 寫法 一 
#!/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 的寫法了。

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

第二種寫法當我們看到 “if (n:=len(ls)) > 3:” 一來我們直接可以看出這個 if 依賴於 n 的值,二來后面的代碼也非常有可能會用到 n ,如果不用的話直接寫成 “if len(ls) > 3:” 不就行了嗎? 

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

 

4、:= 與 = 的關系

看官方的意思 “:=” 是作為 “=” 的一個補充而存在的,並不是想用 “:=” 替換掉 “=”,下面看一下它兩是互補的一個例子

#!/usr/bin/env python3

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

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

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

 

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

# 一 簡化 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM