Python2 倒計時,還不快來掌握 Python3 酷炫的新特性?|原力計劃

2021-01-10 CSDN

作者 | 雲爬蟲技術研究筆記

責編 | 郭芮

出品 | CSDN 博客

Python3.8已經發布近一個月了,距離Python3.0第一個版本發布也將超過10年了。相信很多人還是依舊在使用Python2.7版本,想要遷移到最新版本卻不知道怎麼能夠快速掌握其中最Amazing的方法。

下面這篇文章,我會給大家推薦3.0版本依賴最最新潮的函數和語法,讓你們能夠在Review代碼時候「脫穎而出」!

前言

首先我們先來講幾個時間點:

Python2.7正式停止維護時間 2020年1月1日,距今還有1個多月

Python3.8正式開始發布時間 2019年10月14日,距今1個多月

從這兩個數字我們可以看出,Python3這個大版本已經發展很長的時間了,而距離Python2.7的結束也越來越近了。在距離Python2.7停止維護的一年內,很多優秀開源項目都已經停止了對 2.7 的支持,例如到今年 1 月份,NumPy 將停止支持 Python 2;到今年年末,Ipython、Cython 和 Pandas 等等都將陸續停止支持 Python 2。

所以,為了響應號召,順應趨勢。我們慢慢的向Python3.X去遷移,那我們如何能夠快速的掌握Python3.X版本的精髓呢?下面我們從幾個有趣的新特性入手,這些特性或方法都是 Python 3 各個版本中新加的,它們相比傳統的 Python 方法,更容易解決實踐中的一些問題。

所有的示例都是在 Python 3.7 的環境下編寫的,每個特性示例都給出了其正常工作所需的最低的 Python 版本。

潮流特性

格式化字符串 f-string(最低 Python 版本為 3.6)「如何格式化字符串」這個話題我想是每個開發者在接觸一門新語言的時候都會去學習的語法,而在Python中格式化語法的方式大家通常都會偏向於【Format】或者 【%S】這兩種方法,操作如下:

print("My name is %s" % ('phithon', ))print("My name is %(name)s" % {'name':'phithon'})print("My name is {}".format("bob"))print("My name is {name}".format(name="bob"))

而到了Python3.6版本,推出了新的格式化字符串的靈活方法【f-string】,使用【f-string】編寫的與上面功能相同的代碼是這樣的:

name="bob"print(f"My name is {name}")

我們對比這幾種格式化字符串的方法,可以發現相比於常見的字符串格式符【%S】 或 【Format】 方法,【f-string】 直接在佔位符中插入變量顯得更加方便,也更好理解,關于格式化速度方面可以參考這個博文(https://stackoverflow.com/questions/56587807/why-are-f-strings-faster-than-str-to-parse-values)看看詳細的解釋。

路徑管理庫 Pathlib(最低 Python 版本為 3.4)從上個特性可以看出【f-string】 確實非常強大和美觀,而在文件路徑方面,Python遵循了他們的開發理念:萬物皆是對象,所以他們把路徑也單拎出來搞了一個路徑對象庫,也就是一個處理文件路徑的抽象庫【pathlib】。如果你不知道為什麼應該使用 【pathlib】,請參閱下面這篇 Trey Hunner 編寫的炒雞棒的博文(https://treyhunner.com/2018/12/why-you-should-be-using-pathlib/)以及它的後續版本。

下面我們對比同一案例的新舊兩個版本Python的實現:

from glob import globfile_contents = []for filename in glob('**/*.py', recursive=True):with open(filename) as python_file: file_contents.append(python_file.read())

from pathlib import Pathfile_contents = [ path.read_text()for path in Path.cwd().rglob('*.py')]s')

如上所示,您可以read_text對Path對象使用方法和列表理解,將文件內容全部讀入一個新列表中,相比於使用舊版本Python的實現,在語法和美觀上無疑是更加出色!

類型提示 Type hinting(最低 Python 版本為 3.5)程式語言有很多類型,靜態編譯型語言和動態解釋型語言的對比是軟體工程中一個熱門的話題,幾乎每個人對此有自己的看法。在靜態語言中類型標註無疑是讓人又愛又恨,愛的是編譯速度加快,團隊合作中準確了解函數方法的入參類型,恨的是Coding時極其繁瑣的標註。不過,標註這種極其符合團隊文化的操作還是在Python3中被引入,並且很快得到了人們的喜愛。

defprint_yes_or_no(codition: str) -> bool:pass

枚舉(最低 Python 版本為 3.4)大家在寫Java或者C語言的時候都會接觸到枚舉這個特性,枚舉也是幫我們節省了很多時間,也讓我們的代碼更加美觀。舊版本Python中大家想要實現枚舉的話實現方法五花八門,「八仙過海,各顯神通」,充分發揮了Python的動態語言特性。我們下面舉些例子:

#利用type自建類的騷操作defenum(**enums):return type('Enum', (), enums)Numbers = enum(ONE=1, TWO=2, THREE='three')# Numbers.ONE == 1, Numbers.TWO == 2 and Numbers.THREE == 'three'

#利用type自建類的騷操作升級版defenum(*sequential, **named): enums = dict(zip(sequential, range(len(sequential))), **named)return type('Enum', (), enums)Numbers = enum('ZERO', 'ONE', 'TWO')# Numbers.ZERO == 0 and Numbers.ONE == 1

#有帶值到名稱映射的def enum(*sequential, **named): enums = dict(zip(sequential, range(len(sequential))), **named)reverse = dict((value, key) for key, value in enums.iteritems()) enums['reverse_mapping'] = reversereturntype('Enum', (), enums)# Numbers.reverse_mapping['three'] == 'THREE'

# 更有甚者,利用namedtuple實現的from collections import namedtupledefenum(*keys):return namedtuple('Enum', keys)(*keys)MyEnum = enum('FOO', 'BAR', 'BAZ')# 帶字符數字映射的,像C/C++defenum(*keys):return namedtuple('Enum', keys)(*range(len(keys)))# 帶字典映射的,可以映射出各種類型,不局限於數字defenum(**kwargs):return namedtuple('Enum', kwargs.keys())(*kwargs.values())

看過了以上這麼多騷操作,現在Python3給你淨化一下眼睛,Python3.4新推出通過「Enum」類編寫枚舉的簡單方法。

fromenum import Enum, autoclass Monster(Enum): ZOMBIE = auto() WARRIOR = auto() BEAR = auto()print(Monster.ZOMBIE)for i in Monster: print(i)#Monster.ZOMBIE#Monster.ZOMBIE#Monster.WARRIOR#Monster.BEAR

以上我們可以看出枚舉是符號名稱(成員)的集合,這些符號名稱與唯一的常量值綁定在一起。在枚舉中,可以通過標識對成員進行比較操作,枚舉本身也可以被遍歷。

原生 LRU 緩存(最低 Python 版本為 3.2)緩存是大家在開發中都會用到的一個特性,如果我們準確的使用好它,它會節省我們很多時間和成本。相信很多人初學Python裝飾器的時候都會去實現一個緩存的裝飾器來節省斐波那契函數的計算時間。而Python 3 之後將 LRU(最近最少使用算法)緩存作為一個名為「lru_cache」的裝飾器,使得對緩存的使用非常簡單。

下面是一個簡單的斐波那契函數,我們知道使用緩存將有助於該函數的計算,因為它會通過遞歸多次執行相同的工作。

import timedeffib(number: int) -> int:if number == 0: return0if number == 1: return1return fib(number-1) + fib(number-2)start = time.time()fib(40)print(f'Duration: {time.time() - start}s')# Duration: 30.684099674224854s

我們看到,我們沒用緩存裝飾器的時候計算的時間是30秒左右,現在,我們可以使用「lru_cache」來優化它(這種優化技術被稱為「memoization」)。通過這種優化,我們將執行時間從幾秒降低到了幾納秒。

from functools import lru_cache@lru_cache(maxsize=512)deffib_memoization(number: int) -> int:if number == 0: return0if number == 1: return1return fib_memoization(number-1) + fib_memoization(number-2)start = time.time()fib_memoization(40)print(f'Duration: {time.time() - start}s')# Duration: 6.866455078125e-05s

可以看出,我們在開發計算函數的時候使用緩存裝飾器是多麼提高成本的一種手段,另外,在新版本Python3.8之後,lru_cache現在可直接作為裝飾器而不是作為返回裝飾器的函數。因此這兩種寫法現在都被支持:

@lru_cachedeff(x): ...@lru_cache(maxsize=256)deff(x): ...

擴展的可迭代對象解包(最低 Python 版本為 3.0)Python解包相信在我們初學Python的時候都有所了解,如果我們很多地掌握這個特性,相信是一件非常酷的事情。那什麼是擴展的解包呢?我們可以從pep3132中了解更多,舉個例子:

# Python 3.4 中 print 函數 不允許多個 * 操作>>> print(*[1,2,3], *[3,4]) File "<stdin>", line 1 print(*[1,2,3], *[3,4]) ^SyntaxError: invalid syntax>>>

# 再來看看 python3.5以上版本# 可以使用任意多個解包操作>>> print(*[1], *[2], 3)123>>> *range(4), 4(0, 1, 2, 3, 4)>>> [*range(4), 4][0, 1, 2, 3, 4]>>> {*range(4), 4}{0, 1, 2, 3, 4}>>> {'x': 1, **{'y': 2}}{'x': 1, 'y': 2}

我們可以看到,解包這個操作也算的上Python中極其潮流的玩法了,耍的一手好解包,真的會秀翻全場啊!

Data class 裝飾器(最低 Python 版本為 3.7)Python 3.7 引入了【data class】,新特性大大簡化了定義類對象的代碼量,代碼簡潔明晰。通過使用@dataclass裝飾器來修飾類的設計,可以用來減少對樣板代碼的使用,因為裝飾器會自動生成諸如「__init__()」和「__repr()__」這樣的特殊方法。在官方的文檔中,它們被描述為「帶有預設值的可變命名元組」。

from dataclasses import dataclass@dataclassclassDataClassCard: rank: str suit: str#生成實例queen_of_hearts = DataClassCard('Q', 'Hearts')print(queen_of_hearts.rank)print(queen_of_hearts)print(queen_of_hearts == DataClassCard('Q', 'Hearts'))#Q#DataClassCard(rank='Q', suit='Hearts')#True

而常規的類,按照Python 3.7之前的語法類似於這樣:

classRegularCarddef__init__(self, rank, suit):self.rank = rankself.suit = suitqueen_of_hearts = RegularCard('Q', 'Hearts')print(queen_of_hearts.rank)print(queen_of_hearts)print(queen_of_hearts == RegularCard('Q', 'Hearts'))#'Q'#<__main__.RegularCard object at 0x7fb6eee35d30>#False

雖然這種寫法並沒有使用更多的代碼量,但是我們很容易看到為了初始化,僅僅只是為了初始化一個對象,rank和suit已經重複了三次。此外,如果你試圖使用這個RegularCard類,你會注意到對象的表示不是很具描述性,並且已有的類與新聲明的類是無法比較是否相同的。因為每次聲明都會使用一個新的內存地址,而「==」不止比較類存儲的信息,還比較內存地址是否相同。

dataclass還在底層給我們做了更多的有用的封裝。默認情況下dataclass實現了__repr__方法,可以很好的提供字符串表示;也是了__eq__方法,可以做基本的對象比較。而如果RegularCard想實現上面的功能需要寫大量的聲明,代碼量多的嚇人。

classRegularCard(object):def__init__(self, rank, suit):self.rank = rankself.suit = suitdef__repr__(self):#可以將類的信息列印出來return (f'{self.__class__.__name__}' f'(rank={self.rank!r}, suit={self.suit!r})') #大家可以試著將「!r」去掉或者將其中的r改變為s或a,看看輸出結果會有什麼變化#conversion character: expected 's', 'r', or 'a'def__eq__(self, other):#可以比較類是否相同(不考慮內存地址)if other.__class__ is notself.__class__:return NotImplementedreturn (self.rank, self.suit) == (other.rank, other.suit)

隱式命名空間包(最低 Python 版本為 3.3)一種組織 Python 代碼文件的方式是將它們封裝在程序包中(包含一個「init.py」的文件夾)。下面是官方文檔提供的示例:

sound/ Top-level package __init__.py Initialize the sound package formats/ Subpackage for file format conversions __init__.py wavread.py wavwrite.py aiffread.py aiffwrite.py auread.py auwrite.py . .. effects/ Subpackage for sound effects __init__.py echo.py surround.py reverse.py ... filters/ Subpackage for filters __init__.py equalizer.py vocoder.py karaoke.py ...

在 Python 2 中,上面每個文件夾都必須包含將文件夾轉化為 Python 程序包的「init.py」文件。在 Python 3 中,隨著隱式命名空間包的引入,這些文件不再是必須的了。

sound/ Top-level package __init__.py Initialize the sound package formats/ Subpackage for file format conversions wavread.py wavwrite.py aiffread.py aiffwrite.py auread.py auwrite.py ... effects/ Subpackage for sound effects echo.py surround.py reverse.py ... filters/ Subpackage for filters equalizer.py vocoder.py karaoke.py ...

正如有些人說的那樣,這項工作並沒有像這篇文章說的那麼簡單,官方文檔「PEP 420 Specification」指出,常規的程序包仍然需要「init.py」,把它從一個文件夾中刪除會將該文件夾變成一個本地命名空間包,這會帶來一些額外的限制。本地命名空間包的官方文檔給出了一個很好的示例,並且明確指出了所有的限制。

總結

上面給出的幾個很潮流的特性可能並不是很全,更多的還需要大家去探索符合自己和團隊的玩法,這篇文章只是向大家展示一些比較好玩的Python新功能,掌握它可以幫助你寫出更加Pythonic的代碼。

聲明:本文為CSDN博主「雲爬蟲技術研究筆記」的原創文章,版權歸作者所有。

技術的道路一個人走著極為艱難?

一身的本領得不施展?

優質的文章得不到曝光?

別擔心,

即刻起,CSDN 將為你帶來創新創造創變展現的大舞臺,

相關焦點

  • Python 3.8.0來了!
    新版本較3.7版增加了一大波新功能和優化,來新智元 AI 朋友圈與 AI 大咖一起參與討論吧~ 今天,Python 官網宣布,正式發布 Python 3.8.0!
  • Python入門小迷宮,走完這個迷宮,就能掌握python編程基礎
    這是一個很神奇的迷宮,走完這個迷宮就能掌握python基礎。其實,這是一個用python做的迷宮小遊戲,非常簡單,但對於python初學者來說,還是有一定的挑戰性,但TONOW有源碼和教程,只要跟著python迷宮小遊戲的教程和相應的源碼,不僅很容易就能自己開發出這個遊戲,還能在這個過程中,掌握python編程的基礎哦!
  • 13個小案例輕鬆認識python
    python流行一段時間了,開始的就感覺只是一種新的語言罷了,可是這個世界總是對新事物非常尊崇,平時用的不多,看起來也沒多大動力,結合著平時講VB(信息技術《算法與程序設計》9講)的套路,用案例簡單自學下python,這13個小案例不像網絡上的圖形處理等那麼酷炫,不能做出酷炫的作品,也沒有涉及基礎的算法,但也是python的基礎吧
  • 從0開始學python-6.2 用python讀寫文件
    我們還學習了用python來查找、重命名一個文件。這節課,我們一起學習一下怎麼用python操作一個文件的內容。文件操作對一個文件,我們可以1)讀取裡面的內容、2)往文件裡寫內容、3)追加文件內容。我們來看看用python怎麼做這些事情。打開文件在對文件內容操作之前,我們首先要打開文件。
  • 用一篇短文來告訴大家,學習Python都可以用來幹嘛
    python能做太多有趣的事了,看看我是怎麼玩的1.自動發郵件2.自動化操作excel3.定製酷炫二維碼4.下載視頻、MP35.爬蟲6.HTML\網頁自動生成PDF7.製作可視化圖表8.地理空間分析9.數據分析10連接資料庫11.機器學習如果你不知道如何學習python,入門困難,如果你想從事數據分析,學習分析技術,如果你想學習sql
  • Python微項目分享之重要事件倒計時
    作者:JiawuZhang出品:JiawuLab(ID:jiawulab)微項目系列是JiawuLab原創欄目,每期選取一個自創項目或發現有趣的項目,進行代碼、邏輯分析,達到python學習目的。大家好,我是JiawuZhang,本期微項目是——事件倒計時。項目介紹「11月11日0點0分0秒!」
  • 《小灰教你零基礎學python》-Python入門語言
    程式語言有很多,咱們就學簡單強大的python即可。Python是一種清晰而強大的面向對象程式語言,不過還沒入門的小白不要想多了哈,不是你的對象(女朋友?)Python目前是分成2個大版本,python2 和python3,python是完全免費的,所以不用擔心版權問題,因為python2已經廢棄,所以咱們這套課程完全基於python3。
  • 廣州Python測試培訓
    基礎編程語法;2、使用模塊進行程序設計3、使用Python創建文件、訪問、刪除文件。立即諮詢 02 Python高級編程 教學目標:1、掌握python高級編程,能進行面向對象設計;2、掌握網絡編程協議,實現網絡間點對點通信;3、掌握關係型資料庫MySql開發,熟練編寫SQL語句;
  • python教程之python數學運算
    運算符和操作數一起構成表達式,操作數可以使用標識符表示,如a=3;b=2;c=a*b,表達式是python程序最常見的代碼import mathnum1,num2=eval(input('請輸入兩個數值,逗號分隔->'))#輸入兩個值,分別賦值給num1和num2print(num1,'平方根:',math.sqrt(num1))#計算num1的平方根
  • 如何自學成 Python 大神?這裡有些建議
    掌握基本語法之後,編寫一些簡單的程序,如階乘、斐波納契數列、單數/偶數、計算器等等。下一步是了解列表、集合、元組、字典等特殊的數據結構。再次使用這些技能來解決一些實際問題,並使用這些數據結構來構建程序。
  • Python2 已終結,入手Python 3,你需要這30個技巧
    使用 Python3如果你關注 Python 的話,應該會知道 Python 2 已經於今年(2020 年)1 月 1 日正式棄用了。這份教程的很多例子都是只支持 Python 3 的,如果你還在用 Python 2.1,那也是時候與時俱進了。2.
  • Python數據類型串講(中)
    python中的內建序列有6種:列表、元祖、字符串、Unicode字符串、xrange對象、buffer對象,其中列表和元祖是最常見的序列,應重點掌握。字符串在上一篇文章中已簡單介紹,下面將以字符串為例,對序列的通用操作進行詳講。
  • 成都Python培訓周期多久
    1.掌握Python基礎語法,具備基礎的編程能力2.掌握Linux基本操作命令,掌握MySQL進階內容 階段項目: 1.銀行自動提款機系統實戰    2.英漢詞典    3.歌詞解析器
  • 初識python
    2,python歷史。宏觀上:python2 與 python3 區別:python2 源碼不標準,混亂,重複代碼太多,python3 統一 標準,去除重複代碼。3,python的環境。編譯型:一次性將所有程序編譯成二進位文件。缺點:開發效率低,不能跨平臺。優點:運行速度快。
  • 2019年必知的10大頂級Python庫
    TensorFlow 就像一個計算庫,用於編寫涉及大量 tensor 操作的新算法。由於神經網絡可以很容易地表示為計算圖,因此它們可以使用 TensorFlow 作為 tensor 的一系列操作來實現。另外,tensor 是表示數據的 n 維矩陣。
  • Python開發:Win10創建定時任務執行Python腳本
    :  Win10創建定時任務  電腦桌面→我的電腦→右鍵→管理  計算機管理→系統工具→任務計劃程序→創建基本任務    選擇任務計劃程序    註:創建基礎任務時,選擇的執行程序是pythonw.exe,而不是python.exe,主要原因是pythonw.exe執行python程序是不會出現黑色控制臺窗口,python.exe
  • 成都學習Python開發哪家好
    那麼成都python培訓機構有哪些好呢?成都市不同規模的python培訓機構有什麼不同?沒有任何一家機構所有的課程都是牛逼的,它和人一樣有優點和缺點,除非它只專注於教1-2門課程。大多數培訓機構都不願意這樣做。畢竟有那麼多程式語言,太過於專注會流失掉大量學生,從而造成營收減少的結果。建議您選擇信譽好的老牌Python培訓機構。
  • Python開發簡單爬蟲【學習資料總結】
    URL管理器返回是/否; 2、如果是,調度器會從URL管理器中取出一個待爬URL; 3、調度器將URL傳給下載器,下載網頁內容後返回給調度器; 4、調度器再將返回的網頁內容發送到解析器,解析URL內容,解析完成後返回有價值的數據和新的URL; 5、一方面,調度器將數據傳遞給應用進行數據的收集
  • 科悟學院介紹什麼是Python、python能做什麼?
    首先我們需要安裝一個解釋器,在菜單欄downloads按鈕下選擇對應系統下的版本,安裝版本可選3.8.1版本,下載後與正常安裝軟體操作步驟無異。安裝好後我們怎麼打開使用呢?win系統的同學可以按下win+r鍵,在彈出小窗口輸入cmd命令再回車即可看到彈出的Dos命令面板,接下來我們在Dos面板中輸入 python 即可進入Python的解釋器。
  • 人生苦短,我用Python,那麼問題來了,普通人要學python嗎?
    2、Python納入山東省的小學教材課程,小學生都開始接觸 Python 語言了。3、Python 將加入全國計算機等級考試!教育部考試中心決定自2018年起,在計算機二級考試加入了「Python語言程序設計」科目。4、現在國外國內很多家長已經給孩子報名學習Python編程課程了。在美國,就連嬰幼兒也有專門的編程童書。