關(guān)于我們
書單推薦
新書推薦
|
流暢的Python
本書致力于幫助Python開發(fā)人員挖掘這門語言及相關(guān)程序庫的優(yōu)秀特性,避免重復(fù)勞動,同時寫出簡潔、流暢、易讀、易維護(hù),并且具有地道Python風(fēng)格的代碼。本書尤其深入探討了Python語言的高級用法,涵蓋數(shù)據(jù)結(jié)構(gòu)、Python風(fēng)格的對象、并行與并發(fā),以及元編程等不同的方面。
本書由奮戰(zhàn)在Python開發(fā)一線近20年的Luciano Ramalho執(zhí)筆,Victor Stinner、Alex Martelli等Python大咖擔(dān)綱技術(shù)審稿人,從語言設(shè)計層面剖析編程細(xì)節(jié),兼顧Python 3和Python 2,告訴你Python中不親自動手實踐就無法理解的語言陷阱成因和解決之道,教你寫出風(fēng)格地道的Python代碼。
● Python數(shù)據(jù)模型:理解為什么特殊方法是對象行為一致的關(guān)鍵。 ● 數(shù)據(jù)結(jié)構(gòu):充分利用內(nèi)置類型,理解Unicode文本和字節(jié)二象性。 ● 把函數(shù)視作對象:把Python函數(shù)視作一等對象,并了解這一點對流行的設(shè)計模式的影響。 ● 面向?qū)ο罅?xí)慣用法:通過構(gòu)建類學(xué)習(xí)引用、可變性、接口、運(yùn)算符重載和多重繼承。 ● 控制流程:學(xué)習(xí)使用上下文管理器、生成器、協(xié)程,以及通過concurrent.futures和asyncio包實現(xiàn)的并發(fā)。 ● 元編程:理解特性、描述符、類裝飾器和元類的工作原理。
要不這樣吧,如果編程語言里有個地方你弄不明白,而正好又有個人用了這個功能,那就開槍把他打死。這比學(xué)習(xí)新特性要容易些,然后過不了多久,那些活下來的程序員就會開始用0.9.6版的Python,而且他們只需要使用這個版本中易于理解的那一小部分就好了(眨眼)。1
—— Tim Peters傳奇的核心開發(fā)者,“Python之禪”作者 Python官方教程(https://docs.python.org/3/tutorial/)的開頭是這樣寫的:“Python是一門既容易上手又強(qiáng)大的編程語言。”這句話本身并無大礙,但需要注意的是,正因為它既好學(xué)又好用,所以很多Python程序員只用到了其強(qiáng)大功能的一小部分。 只需要幾個小時,經(jīng)驗豐富的程序員就能學(xué)會用Python寫出實用的程序。然而隨著這最初高產(chǎn)的幾個小時變成數(shù)周甚至數(shù)月,在那些先入為主的編程語言的影響下,開發(fā)者們會慢慢地寫出帶著“口音”的Python代碼。即便Python是你的初戀,也難逃此命運(yùn)。因為在學(xué)校里,抑或是那些入門書上,教授者往往會有意避免只跟語言本身相關(guān)的特性。 另外,向那些已在其他語言領(lǐng)域里有了豐富經(jīng)驗的程序員介紹Python的時候,我還發(fā)現(xiàn)了一個問題:人們總是傾向于尋求自己熟悉的東西。受到其他語言的影響,你大概能猜到Python會支持正則表達(dá)式,然后就會去查閱文檔。但是如果你從來沒見過元組拆包(tuple unpacking),也沒聽過描述符(descriptor)這個概念,那么估計你也不會特地去搜索它們,然后就永遠(yuǎn)失去了使用這些Python獨(dú)有的特性的機(jī)會。這也是本書試圖解決的一個問題。 這本書并不是一本完備的Python使用手冊,而是會強(qiáng)調(diào)Python作為編程語言獨(dú)有的特性,這些特性或者是只有Python才具備的,或者是在其他大眾語言里很少見的。Python語言核心以及它的一些庫會是本書的重點。盡管Python的包索引現(xiàn)在已經(jīng)有6萬多個庫了,而且其中很多都異常實用,但是我?guī)缀醪粫岬絇ython標(biāo)準(zhǔn)庫以外的包。 注1: 給comp.lang.python Usenet小組的留言,2002年12月23日,“Acrimony in c.l.p”(https://mail.python.org/pipermail/python-list/2002-December/147293.html)。 目標(biāo)讀者 本書的目標(biāo)讀者是那些正在使用Python,又想熟悉Python 3 的程序員。如果你懂Python 2, 但是想遷移到Python 3.4 或者更新的版本,也沒問題。在寫這本書的時候,大多數(shù)專業(yè)Python 程序員用的還是Python 2,因此如果書中出現(xiàn)來自Python 3 的特性,讀者可能會感到陌生,我也會特別地做出解釋。 然而,本書的主要目的是為了充分地展現(xiàn)Python 3.4 的魅力,因此我不會一字一句地說明如何讓本書的代碼在舊版本里正常運(yùn)行。本書中的大多數(shù)例子稍做修改(甚至不用修改) 就可以在Python 2.7 里面跑起來,但是有些例子,如果追求向下兼容,就會需要大量的重寫。 話雖如此,我還是認(rèn)為,即便你無法從Python 2.7 里脫身,這本書也會對你很有幫助,因為Pyhon 語言的核心概念是不會變的。Python 3 也不是一門全新的語言,大多數(shù)的改動花一下午大概就能適應(yīng),官方文檔里“Python 3.0 的新特性”一節(jié)(https://docs.python. org/3.0/whatsnew/3.0.html)就是很好的切入點。固然,自2009 年發(fā)布以來,Python 3.0 也在變化,但是這些變化比起Python 3.0 和Python 2.0 之間的區(qū)別,并沒有那么重要。 如果你尚不清楚自己對Python 的熟悉程度能否跟得上本書的內(nèi)容,建議你回頭看看Python 的官方教程。注意,除非是跟Python 3 的新特性有關(guān),教程里的其他內(nèi)容本書不會重復(fù)。 非目標(biāo)讀者 如果你才剛剛開始學(xué)Python,本書的內(nèi)容可能會顯得有些“超綱”。比難懂更糟的是,如果在學(xué)習(xí)Python 的過程中過早接觸本書的內(nèi)容,你可能會誤以為所有的Python 代碼都應(yīng)該利用特殊方法和元編程(metaprogramming)技巧。我們知道,不成熟的抽象和過早的優(yōu)化一樣,都會壞事。 本書的結(jié)構(gòu) 如果你是本書的目標(biāo)讀者,那你應(yīng)該可以從本書的任意一章開始閱讀,但是如果按照我寫作時的構(gòu)思來的話,本書一共分為六個獨(dú)立的部分,每個部分內(nèi)的章節(jié)最好按照順序來讀。 在介紹讓你自己實現(xiàn)某些功能的方法之前,我通常會先把現(xiàn)成可用的工具講清楚。比如說第二部分的第2 章覆蓋了序列類型(sequence type),但是像collections.deque 這種類可能就會一帶而過。一直到第四部分,我們才會看看如何從抽象基類(abstract base class, ABC)中獲利,抽象基類則被封裝在collections.abc 這個包里。如果想創(chuàng)建自己的ABC,你可能得看到第四部分的最后一些內(nèi)容才行,因為我一直覺得,如果沒有熟練使用ABC 的經(jīng)驗,貿(mào)然去實現(xiàn)一套自己的東西是不合適的。 這樣做有幾個好處。第一,知道有什么現(xiàn)成的工具可用,能避免重新發(fā)明輪子。畢竟我們使用現(xiàn)有集合類型(collection type)的概率要遠(yuǎn)大于自己動手寫一套新的。第二,這樣一來,在討論如何寫新類型之前,我們能夠有更多的機(jī)會來了解這些現(xiàn)成類的高級用法。第三,比起從零開始構(gòu)建一個ABC,繼承已有的ABC 庫應(yīng)該會簡單一些。最后,我認(rèn)為在看過一些實際的案例之后,理解抽象會更輕松。 當(dāng)然,這樣也會帶來一些不便之處,比如書里的向前引用就會分散在各個不同的章節(jié)里面。但是經(jīng)過上述這番梳理,我想這一點不便之處也是可以容忍的。 下面是本書每一部分的主題。 第一部分 第一部分只有單獨(dú)的一章,講解的是Python 的數(shù)據(jù)模型(data model),以及如何為了保證行為一致性而使用特殊方法(比如__repr__),畢竟Python 的一致性是出了名的。其實整本書幾乎都是在講解Python 的數(shù)據(jù)模型,第1 章算是一個概覽。 第二部分 第二部分包含了各種集合類型:序列(sequence)、映射(mapping)和集合(set),另外還提及了字符串(str)和字節(jié)序列(bytes)的區(qū)分。說起來,最后這一點也是讓親者(Python 3 用戶)快,仇者(Python 2 用戶)痛的一個關(guān)鍵,因為這個區(qū)分致使Python 2 代碼遷移到Python 3 的難度陡增。第二部分的目標(biāo)是幫助讀者回憶起Python 內(nèi)置的類庫,順帶解釋這些類庫的一些不太直觀的地方。具體的例子有Python 3 如何在我們觀察不到的地方對dict 的鍵重新排序,或者是排序有區(qū)域(locale)依賴的字符串時的注意事項。為了達(dá)到本部分的目標(biāo),有些地方的講解會比較大而全,像序列類型和映射類型的變種就是這樣;有時則會寫得很深入,比方說我會對dict 和set 底層的散列表進(jìn)行深層次的討論。 第三部分 如何把函數(shù)作為一等對象(first-order object)來使用。第三部分首先會解釋前面這句話是什么意思,然后話題延伸到這個概念對那些被廣泛使用的設(shè)計模型的影響,最后讀者會看到如何利用閉包(closure)的概念來實現(xiàn)函數(shù)裝飾器(function decorator)。這一部分的話題還包括Python 的這些基本概念:可調(diào)用(callable)、函數(shù)屬性(function attribute)、內(nèi)省(introspection)、參數(shù)注解(parameter annotation)和Python 3 里新出現(xiàn)的nonlocal 聲明。 第四部分 到了這里,書的重點轉(zhuǎn)移到了類的構(gòu)建上面。雖然在第二部分里的例子里就有類聲明(class declaration)的出現(xiàn),但是第四部分會呈現(xiàn)更多的類。和任何面向?qū)ο笳Z言一樣, Python 還有些自己的特性,這些特性可能并不會出現(xiàn)在你我學(xué)習(xí)基于類的編程的語言中。這一部分的章節(jié)解釋了引用(reference)的原理、“可變性”的概念、實例的生命周期、如何構(gòu)建自定義的集合類型和ABC、多重繼承該怎么理順、什么時候應(yīng)該使用操作符重載及其方法。 第五部分 Python 中有些結(jié)構(gòu)和庫不再滿足于諸如條件判斷、循環(huán)和子程序(subroutine)之類的順序控制流程,第五部分的筆墨會集中在這些構(gòu)造和庫上。我們會從生成器(generator)起步,然后話題會轉(zhuǎn)移到上下文管理器(context manager)和協(xié)程(coroutine),其中會涵蓋新增的功能強(qiáng)大但又不容易理解的yield from 語法。這一部分以并發(fā)性和面向事件的I/O 來結(jié)尾,其中跟并發(fā)性相關(guān)的是collections.futures 這個很新的包,它借助futures 包把線程和進(jìn)程的概念給封裝了起來;而跟面向事件I/O 相關(guān)的則是asyncio,它的背后是基于協(xié)程和yield from 的futures 包。 第六部分 第六部分的開頭會講到如何動態(tài)創(chuàng)建帶屬性的類,用以處理諸如JSON 這類半結(jié)構(gòu)化的數(shù)據(jù)。然后會從大家已經(jīng)熟悉的特性(property)機(jī)制入手,用描述符從底層來解釋Python 對象屬性的存取。同時,函數(shù)、方法和描述符的關(guān)系也會被梳理一遍。第六部分會從頭至尾地實現(xiàn)一個字段驗證器,在這個過程中我們會遇到一些微妙的問題,然后在最后一章中就自然引出像類裝飾器(class decorator)和元類(metaclass)這些高級的概念。 ……
Luciano Ramalho,從1998年起就成為了Python程序員。他是Python軟件基金會的成員,Python.pro.br(巴西的一家培訓(xùn)公司)的共同所有者,還是巴西眾創(chuàng)空間Garoa Hacker Clube的聯(lián)合創(chuàng)始人。他領(lǐng)導(dǎo)過多個軟件開發(fā)團(tuán)隊,還在巴西的媒體、銀行和政府部門教授Python課程。
安道,專注于現(xiàn)代計算機(jī)技術(shù)的自由翻譯,譯有《Flask Web 開發(fā)》《Python 網(wǎng)絡(luò)編程攻略》《Ruby on Rails 教程》等書。 吳珂,現(xiàn)為Airbnb公司軟件工程師,所在團(tuán)隊主要負(fù)責(zé)開發(fā)和維護(hù)各類可伸縮、高性能服務(wù),并在Airbnb內(nèi)推廣面向服務(wù)的系統(tǒng)架構(gòu)。在分布式系統(tǒng)、云存儲服務(wù)和跨平臺SDK開發(fā),以及大規(guī)模數(shù)據(jù)處理等方面有多年經(jīng)驗。
前言 xvii
第一部分 序幕 第1章 Python 數(shù)據(jù)模型 2 1.1 一摞 Python 風(fēng)格的紙牌 3 1.2 如何使用特殊方法 6 1.2.1 模擬數(shù)值類型 7 1.2.2 字符串表示形式 9 1.2.3 算術(shù)運(yùn)算符 10 1.2.4 自定義的布爾值 10 1.3 特殊方法一覽 10 1.4 為什么 len 不是普通方法 12 1.5 本章小結(jié) 12 1.6 延伸閱讀 13 第二部分 數(shù)據(jù)結(jié)構(gòu) 第2章 序列構(gòu)成的數(shù)組 16 2.1 內(nèi)置序列類型概覽 17 2.2 列表推導(dǎo)和生成器表達(dá)式 18 2.3 元組不僅僅是不可變的列表 22 2.4 切片 28 2.5 對序列使用 + 和 * 31 2.6 序列的增量賦值 33 2.7 list.sort 方法和內(nèi)置函數(shù) sorted 36 2.8 用 bisect 來管理已排序的序列 37 2.9 當(dāng)列表不是首選時 41 2.10 本章小結(jié) 49 2.11 延伸閱讀 50 第3章 字典和集合 54 3.1 泛映射類型 54 3.2 字典推導(dǎo) 56 3.3 常見的映射方法 57 3.4 映射的彈性鍵查詢 61 3.5 字典的變種 65 3.6 子類化 UserDict 65 3.7 不可變映射類型 67 3.8 集合論 68 3.9 dict 和 set 的背后 73 3.10 本章小結(jié) 80 3.11 延伸閱讀 81 第4章 文本和字節(jié)序列 83 4.1 字符問題 84 4.2 字節(jié)概要 85 4.3 基本的編解碼器 88 4.4 了解編解碼問題 89 4.5 處理文本文件 94 4.6 為了正確比較而規(guī)范化 Unicode 字符串 99 4.7 Unicode 文本排序 105 4.8 Unicode 數(shù)據(jù)庫 108 4.9 支持字符串和字節(jié)序列的雙模式 API 109 4.10 本章小結(jié) 112 4.11 延伸閱讀 113 第三部分 把函數(shù)視作對象 第5章 一等函數(shù) 118 5.1 把函數(shù)視作對象 119 5.2 高階函數(shù) 120 5.3 匿名函數(shù) 122 5.4 可調(diào)用對象 122 5.5 用戶定義的可調(diào)用類型 123 5.6 函數(shù)內(nèi)省 124 5.7 從定位參數(shù)到僅限關(guān)鍵字參數(shù) 126 5.8 獲取關(guān)于參數(shù)的信息 127 5.9 函數(shù)注解 131 5.10 支持函數(shù)式編程的包 132 5.11 本章小結(jié) 137 5.12 延伸閱讀 137 第6章 使用一等函數(shù)實現(xiàn)設(shè)計模式 141 6.1 案例分析:重構(gòu)“策略”模式 142 6.2 “命令”模式 150 6.3 本章小結(jié) 151 6.4 延伸閱讀 152 第7章 函數(shù)裝飾器和閉包 154 7.1 裝飾器基礎(chǔ)知識 155 7.2 Python 何時執(zhí)行裝飾器 156 7.3 使用裝飾器改進(jìn)“策略”模式 157 7.4 變量作用域規(guī)則 159 7.5 閉包 161 7.6 nonlocal 聲明 164 7.7 實現(xiàn)一個簡單的裝飾器 165 7.8 標(biāo)準(zhǔn)庫中的裝飾器 168 7.9 疊放裝飾器 172 7.10 參數(shù)化裝飾器 173 7.11 本章小結(jié) 177 7.12 延伸閱讀 178 第四部分 面向?qū)ο髴T用法 第8章 對象引用、可變性和垃圾回收 182 8.1 變量不是盒子 183 8.2 標(biāo)識、相等性和別名 184 8.3 默認(rèn)做淺復(fù)制 187 8.4 函數(shù)的參數(shù)作為引用時 190 8.5 del 和垃圾回收 195 8.6 弱引用 196 8.7 Python 對不可變類型施加的把戲 199 8.8 本章小結(jié) 201 8.9 延伸閱讀 201 第9章 符合 Python 風(fēng)格的對象 205 9.1 對象表示形式 206 9.2 再談向量類 206 9.3 備選構(gòu)造方法 208 9.4 classmethod 與 staticmethod 209 9.5 格式化顯示 210 9.6 可散列的 Vector2d 213 9.7 Python 的私有屬性和“受保護(hù)的”屬性 218 9.8 使用 __slots__ 類屬性節(jié)省空間 220 9.9 覆蓋類屬性 222 9.10 本章小結(jié) 224 9.11 延伸閱讀 225 第10章 序列的修改、散列和切片 229 10.1 Vector 類:用戶定義的序列類型 230 10.2 Vector 類第1 版:與 Vector2d 類兼容 230 10.3 協(xié)議和鴨子類型 232 10.4 Vector 類第2 版:可切片的序列 233 10.5 Vector 類第3 版:動態(tài)存取屬性 237 10.6 Vector 類第4 版:散列和快速等值測試 240 10.7 Vector 類第5 版:格式化 244 10.8 本章小結(jié) 251 10.9 延伸閱讀 251 第11章 接口:從協(xié)議到抽象基類 256 11.1 Python 文化中的接口和協(xié)議 257 11.2 Python 喜歡序列 258 11.3 使用猴子補(bǔ)丁在運(yùn)行時實現(xiàn)協(xié)議 260 11.4 Alex Martelli 的水禽 262 11.5 定義抽象基類的子類 266 11.6 標(biāo)準(zhǔn)庫中的抽象基類 267 11.7 定義并使用一個抽象基類 270 11.8 Tombola 子類的測試方法 278 11.9 Python 使用 register 的方式 281 11.10 鵝的行為有可能像鴨子 281 11.11 本章小結(jié) 283 11.12 延伸閱讀 284 第12章 繼承的優(yōu)缺點 289 12.1 子類化內(nèi)置類型很麻煩 289 12.2 多重繼承和方法解析順序 292 12.3 多重繼承的真實應(yīng)用 296 12.4 處理多重繼承 298 12.5 一個現(xiàn)代示例:Django 通用視圖中的混入 301 12.6 本章小結(jié) 304 12.7 延伸閱讀 304 第13章 正確重載運(yùn)算符 307 13.1 運(yùn)算符重載基礎(chǔ) 308 13.2 一元運(yùn)算符 308 13.3 重載向量加法運(yùn)算符 + 310 13.4 重載標(biāo)量乘法運(yùn)算符 * 315 13.5 眾多比較運(yùn)算符 318 13.6 增量賦值運(yùn)算符 321 13.7 本章小結(jié) 325 13.8 延伸閱讀 326 第五部分 控制流程 第14章 可迭代的對象、迭代器和生成器 330 14.1 Sentence 類第1 版:單詞序列 331 14.2 可迭代的對象與迭代器的對比 334 14.3 Sentence 類第2 版:典型的迭代器 337 14.4 Sentence 類第3 版:生成器函數(shù) 339 14.5 Sentence 類第4 版:惰性實現(xiàn) 343 14.6 Sentence 類第5 版:生成器表達(dá)式 344 14.7 何時使用生成器表達(dá)式 345 14.8 另一個示例:等差數(shù)列生成器 346 14.9 標(biāo)準(zhǔn)庫中的生成器函數(shù) 349 14.10 Python 3.3 中新出現(xiàn)的句法: yield from 357 14.11 可迭代的歸約函數(shù) 358 14.12 深入分析 iter 函數(shù) 359 14.13 案例分析:在數(shù)據(jù)庫轉(zhuǎn)換工具中使用生成器 360 14.14 把生成器當(dāng)成協(xié)程 362 14.15 本章小結(jié) 362 14.16 延伸閱讀 363 第15章 上下文管理器和 else 塊 368 15.1 先做這個,再做那個: if 語句之外的 else 塊 369 15.2 上下文管理器和 with 塊 370 15.3 contextlib 模塊中的實用工具 374 15.4 使用 @contextmanager 375 15.5 本章小結(jié) 378 15.6 延伸閱讀 378 第16章 協(xié)程 381 16.1 生成器如何進(jìn)化成協(xié)程 382 16.2 用作協(xié)程的生成器的基本行為 382 16.3 示例:使用協(xié)程計算移動平均值 385 16.4 預(yù)激協(xié)程的裝飾器 386 16.5 終止協(xié)程和異常處理 388 16.6 讓協(xié)程返回值 391 16.7 使用 yield from 393 16.8 yield from 的意義 398 16.9 使用案例:使用協(xié)程做離散事件仿真 403 16.10 本章小結(jié) 410 16.11 延伸閱讀 411 第17章 使用期物處理并發(fā) 416 17.1 示例:網(wǎng)絡(luò)下載的三種風(fēng)格 416 17.2 阻塞型 I/O 和 GIL 424 17.3 使用 concurrent.futures 模塊啟動進(jìn)程 424 17.4 實驗 Executor.map 方法 426 17.5 顯示下載進(jìn)度并處理錯誤 429 17.6 本章小結(jié) 437 17.7 延伸閱讀 438 第18章 使用 asyncio 包處理并發(fā) 442 18.1 線程與協(xié)程對比 443 18.2 使用 asyncio 和 aiohttp 包下載 450 18.3 避免阻塞型調(diào)用 454 18.4 改進(jìn) asyncio 下載腳本 456 18.5 從回調(diào)到期物和協(xié)程 462 18.6 使用 asyncio 包編寫服務(wù)器 466 18.7 本章小結(jié) 475 18.8 延伸閱讀 476 第六部分 元編程 第19章 動態(tài)屬性和特性 482 19.1 使用動態(tài)屬性轉(zhuǎn)換數(shù)據(jù) 483 19.2 使用特性驗證屬性 498 19.3 特性全解析 500 19.4 定義一個特性工廠函數(shù) 504 19.5 處理屬性刪除操作 506 19.6 處理屬性的重要屬性和函數(shù) 507 19.7 本章小結(jié) 510 19.8 延伸閱讀 510 第20章 屬性描述符 514 20.1 描述符示例:驗證屬性 514 20.2 覆蓋型與非覆蓋型描述符對比 526 20.3 方法是描述符 531 20.4 描述符用法建議 533 20.5 描述符的文檔字符串和覆蓋刪除操作 534 20.6 本章小結(jié) 535 20.7 延伸閱讀 536 第21章 類元編程 538 21.1 類工廠函數(shù) 539 21.2 定制描述符的類裝飾器 541 21.3 導(dǎo)入時和運(yùn)行時比較 543 21.4 元類基礎(chǔ)知識 547 21.5 定制描述符的元類 552 21.6 元類的特殊方法 __prepare__ 554 21.7 類作為對象 556 21.8 本章小結(jié) 557 21.9 延伸閱讀 557 結(jié)語 560 附錄 A 輔助腳本 563 Python 術(shù)語表 588 作者簡介 600 關(guān)于封面 600
你還可能感興趣
我要評論
|