免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
一名神級程序員花了半個月:把這本書的全部重點都整理好了!超長

起步

這本書有21個章節(jié), 整理也是根據(jù)這些章節(jié)過來.

第一章: python數(shù)據(jù)模型

第二章: 序列構(gòu)成的數(shù)組

這部分主要是介紹序列, 著重介紹數(shù)組和元組的一些高級用法.

序列按照容納數(shù)據(jù)的類型可以分為:

  • 容器序列 : list、tuple 和 collections.deque 這些序列能存放不同類型的數(shù)據(jù)

  • 扁平序列 : str、bytes、bytearray、memoryview 和 array.array,這類序列只能容納一種類型.

如果按照是否能被修改可以分為:

  • 可變序列 : list、bytearray、array.array、collections.deque 和 memoryview

  • 不可變序列 : tuple、str 和 bytes

列表推導

列表推導是構(gòu)建列表的快捷方式, 可讀性更好且效率更高.

例如, 把一個字符串變成unicode的碼位列表的例子, 一般:

第三章: 字典和集合

defaultdict:處理找不到的鍵的一個選擇

當某個鍵不在映射里, 我們也希望也能得到一個默認值. 這就是 defaultdict , 它是 dict 的子類, 并實現(xiàn)了 __missing__ 方法.

不可變映射類型

說到不可變, 第一想到的肯定是元組, 但是對于字典來說, 要將key和value的對應(yīng)關(guān)系變成不可變, types 模塊的 MappingPrype 可以做到:

第四章: 文本和字節(jié)序列

本章討論了文本字符串和字節(jié)序列, 以及一些編碼上的轉(zhuǎn)換. 本章討論的 str指的是python3下的.

字符問題

如果字符序列和預(yù)期不符, 在進行解碼或編碼時容易拋出 Unicode*Error的異常. 造成這種錯誤是因為目標編碼中沒有定義某個字符(沒有定義某個碼位對應(yīng)的字符), 這里說說解決這類問題的方式.

unicode文本排序

對于字符串來說, 比較的碼位. 所以在非 ascii 字符時, 得到的結(jié)果可能會不盡人意.

第五章: 一等函數(shù)

高階函數(shù)

高階函數(shù)就是接受函數(shù)作為參數(shù), 或者把函數(shù)作為返回結(jié)果的函數(shù). 如 map , filter , reduce等.

第六章: 使用一等函數(shù)實現(xiàn)設(shè)計模式

雖然設(shè)計模式與語言無關(guān), 但這并不意味著每一個模式都能在每一個語言中使用. Gamma 等人合著的 《設(shè)計模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》 一書中有 23 個模式, 其中有 16
個在動態(tài)語言中'不見了, 或者簡化了'.

這里不舉例設(shè)計模式, 因為書里的模式不常用.

第七章: 函數(shù)裝飾器和閉包

函數(shù)裝飾器用于在源碼中“標記”函數(shù),以某種方式增強函數(shù)的行為。這是一項強大的功 能,但是若想掌握,必須理解閉包。

修飾器和閉包經(jīng)常在一起討論, 因為修飾器就是閉包的一種形式. 閉包還是回調(diào)式異步編程和函數(shù)式編程風格的基礎(chǔ).

裝飾器基礎(chǔ)知識

裝飾器是可調(diào)用的對象, 其參數(shù)是另一個函數(shù)(被裝飾的函數(shù)). 裝飾器可能會處理被 裝飾的函數(shù), 然后把它返回, 或者將其替換成另一個函數(shù)或可調(diào)用對象.

閉包

閉包其實挺好理解的, 當匿名函數(shù)出現(xiàn)的時候, 才使得這部分難以掌握. 簡單簡短的解釋閉包就是:

名字空間與函數(shù)捆綁后的結(jié)果被稱為一個閉包(closure).

如果兩個變量都是指向同一個對象, 我們通常會說變量是另一個變量的 別名 .

在==和is之間選擇運算符 == 是用來判斷兩個對象值是否相等(注意是對象值). 而 is 則是用于判斷兩個變量是否指向同一個對象, 或者說判斷變量是不是兩一個的別名, is 并不關(guān)心對象的值. 從使用上, == 使用比較多, 而 is 的執(zhí)行速度比較快.

函數(shù)的參數(shù)做引用時

python中的函數(shù)參數(shù)都是采用共享傳參. 共享傳參指函數(shù)的各個形式參數(shù)獲得實參中各個引用的副本. 也就是說, 函數(shù)內(nèi)部的形參 是實參的別名.

這種方案就是當傳入?yún)?shù)是可變對象時, 在函數(shù)內(nèi)對參數(shù)的修改也就是對外部可變對象進行修改. 但這種參數(shù)試圖重新賦值為一個新的對象時則無效, 因為這只是相當于把參數(shù)作為另一個東西的引用, 原有的對象并不變. 也就是說, 在函數(shù)內(nèi), 參數(shù)是不能把一個對象替換成另一個對象的.

不要使用可變類型作為參數(shù)的默認值

參數(shù)默認值是個很棒的特性. 對于開發(fā)者來說, 應(yīng)該避免使用可變對象作為參數(shù)默認值. 因為如果參數(shù)默認值是可變對象, 而且修改了它的內(nèi)容, 那么后續(xù)的函數(shù)調(diào)用上都會收到影響.

del和垃圾回收

在python中, 當一個對象失去了最后一個引用時, 會當做垃圾, 然后被回收掉. 雖然python提供了 del 語句用來刪除變量. 但實際上只是刪除了變量和對象之間的引用, 并不一定能讓對象進行回收, 因為這個對象可能還存在其他引用.

在CPython中, 垃圾回收主要用的是引用計數(shù)的算法. 每個對象都會統(tǒng)計有多少引用指向自己. 當引用計數(shù)歸零時, 意味著這個對象沒有在使用, 對象就會被立即銷毀.

符合Python風格的對象

得益于 Python 數(shù)據(jù)模型,自定義類型的行為可以像內(nèi)置類型那樣自然。實現(xiàn)如此自然的 行為,靠的不是繼承,而是鴨子類型(duck typing):我們只需按照預(yù)定行為實現(xiàn)對象所 需的方法即可。

對象表示形式

每門面向?qū)ο蟮恼Z言至少都有一種獲取對象的字符串表示形式的標準方式。Python 提供了 兩種方式。

Python中的把使用一個下劃線前綴標記的屬性稱為'受保護的'屬性

使用slots類屬性節(jié)省空間

第十一章: 接口:從協(xié)議到抽象基類

這些協(xié)議定義為非正式的接口, 是讓編程語言實現(xiàn)多態(tài)的方式. 在python中, 沒有 interface 關(guān)鍵字, 而且除了抽象基類, 每個類都有接口: 所有類都可以自行實現(xiàn) __getitem____add__ .

有寫規(guī)定則是程序員在開發(fā)過程中慢慢總結(jié)出來的, 如受保護的屬性命名采用單個前導下劃線, 還有一些編碼規(guī)范之類的.

協(xié)議是接口, 但不是正式的, 這些規(guī)定并不是強制性的, 一個類可能只實現(xiàn)部分接口, 這是允許的.

既然有非正式的協(xié)議, 那么有沒有正式的協(xié)議呢? 有, 抽象基類就是一種強制性的協(xié)議.

抽象基類要求其子類需要實現(xiàn)定義的某個接口, 且抽象基類不能實例化.

Python文化中的接口和協(xié)議

引入抽象基類之前, python就已經(jīng)非常成功了, 即使現(xiàn)在也很少使用抽象基類. 通過鴨子類型和協(xié)議, 我們把協(xié)議定義為非正式接口, 是讓python實現(xiàn)多態(tài)的方式.

另一邊面, 不要覺得把公開數(shù)據(jù)屬性放入對象的接口中不妥, 如果需要, 總能實現(xiàn)讀值和設(shè)值方法, 把數(shù)據(jù)屬性變成特性. 對象公開方法的自己, 讓對象在系統(tǒng)中扮演特定的角色. 因此, 接口是實現(xiàn)特定角色的方法集合.

序列協(xié)議是python最基礎(chǔ)的協(xié)議之一, 即便對象只實現(xiàn)那個協(xié)議最基本的一部分, 解釋器也會負責地處理.

水禽和抽象基類

鴨子類型在很多情況下十分有用, 但是隨著發(fā)展, 通常由了更好的方式.

近代, 屬和種基本是根據(jù)表型系統(tǒng)學分類的, 鴨科屬于水禽, 而水禽還包括鵝, 鴻雁等. 水禽是對某一類表現(xiàn)一致進行的分類, 他們有一些統(tǒng)一'描述'部分.

因此, 根據(jù)分類的演化, 需要有個水禽類型, 只要 cls 是抽象基類, 即 cls 的元類是 abc.ABCMeta , 就可以使用 isinstance(obj, cls) 來進行判斷.

與具類相比, 抽象基類有很多理論上的優(yōu)點, 被注冊的類必須滿足抽象基類對方法和簽名的要求, 更重要的是滿足底層語義契約.

標準庫中的抽象基類

大多數(shù)的標準庫的抽象基類在 collections.abc 模塊中定義. 少部分在 numbersio 包中有一些抽象基類. 標準庫中有兩個 abc 模塊, 這里只討論 collections.abc .

這個模塊中定義了 16 個抽象基類.

Iterable、Container 和 Sized各個集合應(yīng)該繼承這三個抽象基類,或者至少實現(xiàn)兼容的協(xié)議。 Iterable 通過 __iter__ 方法支持迭代,Container 通過 __contains__ 方法支持 in 運算符,Sized 通過 __len__ 方法支持 len() 函數(shù)。

Sequence、Mapping 和 Set這三個是主要的不可變集合類型,而且各自都有可變的子類。

MappingView在 Python3 中,映射方法 .items().keys().values() 返回的對象分別是 ItemsView、KeysView 和 ValuesView 的實例。前兩個類還從 Set 類繼承了豐富的接 口。

Callable 和 Hashable這兩個抽象基類與集合沒有太大的關(guān)系,只不過因為 collections.abc是標準庫中 定義抽象基類的第一個模塊,而它們又太重要了,因此才把它們放到 collections.abc 模塊中。我從未見過 CallableHashable 的子類。這兩個抽象基類的主要作用是為內(nèi) 置函數(shù) isinstance 提供支持,以一種安全的方式判斷對象能不能調(diào)用或散列。

Iterator注意它是 Iterable 的子類。

第十二章: 繼承的優(yōu)缺點

很多人覺得多重繼承得不償失, 那些不支持多繼承的編程語言好像也沒什么損失.

子類化內(nèi)置類型很麻煩

python2.2 以前, 內(nèi)置類型(如list, dict)是不能子類化的. 它們是不能被其他類所繼承的, 原因是內(nèi)置類型是C語言實現(xiàn)的, 不會調(diào)用用戶定義的類覆蓋的方法.

至于內(nèi)置類型的子類覆蓋的方法會不會隱式調(diào)用, CPython 官方也沒有制定規(guī)則. 基本上, 內(nèi)置類型的方法不會調(diào)用子類覆蓋的方法. 例如, dict 的子類覆蓋的 __getitem__ 方法不會覆蓋內(nèi)置類型的 get() 方法調(diào)用.

多重繼承和方法解析順序

任何實現(xiàn)多重繼承的語言都要處理潛在的命名沖突,這種沖突由不相關(guān)的祖先類實現(xiàn)同名 方法引起。這種沖突稱為“菱形問題”,如圖.

Python 會按照特定的順序遍歷繼承 圖。這個順序叫方法解析順序(Method Resolution Order,MRO)。類都有一個名為 mro 的屬性,它的值是一個元組,按照方法解析順序列出各個超類,從當前類一直 向上,直到 object 類。

第十三章: 正確重載運算符

在python中, 大多數(shù)的運算符是可以重載的, 如 == 對應(yīng)了 __eq__ , + 對應(yīng) __add__ .

某些運算符不能重載, 如 is, and, or, and .

第十四章: 可迭代的對象、迭代器和生成器

迭代是數(shù)據(jù)處理的基石. 掃描內(nèi)存中放不下的數(shù)據(jù)集時, 我們要找到一種惰性獲取數(shù)據(jù)的方式, 即按需一次獲取一個數(shù)據(jù). 這就是 迭代器模式 .

python中有 yield 關(guān)鍵字, 用于構(gòu)建 生成器(generator) , 其作用用于迭代器一樣.

所有的生成器都是迭代器, 因為生成器完全實現(xiàn)了迭代器的接口.

檢查對象 x 是否迭代, 最準確的方法是調(diào)用 iter(x) , 如果不可迭代, 則拋出 TypeError 異常. 這個方法比 isinstance(x, abc.Iterable) 更準確, 因為它還考慮到遺留的 __getitem__ 方法.

可迭代的對象與迭代器的對比

我們需要對可迭代的對象進行一下定義:

使用 iter 內(nèi)置函數(shù)可以獲取迭代器的對象。如果對象實現(xiàn)了能返回迭代器的 iter 方法,那么對象就是可迭代的。序列都可以迭代;實現(xiàn)了 getitem 方 法,而且其參數(shù)是從零開始的索引,這種對象也可以迭代。

我們要明確可迭代對象和迭代器之間的關(guān)系: 從可迭代的對象中獲取迭代器.

標準的迭代器接口有兩個方法:

  • __next__ : 返回下一個可用的元素, 如果沒有元素了, 拋出 StopIteration 異常.

  • __iter__ : 返回 self , 以便咋應(yīng)該使用可迭代對象的地方使用迭代器.

典型的迭代器

為了清楚地說明可迭代對象與迭代器之間的重要區(qū)別, 我們將兩者分開, 寫成兩個類:

這個例子主要是為了區(qū)分可迭代對象和迭代器, 這種情況工作量一般比較大, 程序員也不愿這樣寫.

生成器表達式

生成器表達式可以理解為列表推導的惰性版本: 不會迫切地構(gòu)建列表, 而是返回一個生成器, 按需惰性生成元素. 也就是, 如果列表推導是產(chǎn)出列表的工廠, 那么生成器表達式就是產(chǎn)出生成器的工廠.

標準庫中的生成器函數(shù)

用于映射的生成器函數(shù)

模塊函數(shù)說明
itertoolsaccumulate(it, [func])產(chǎn)出累積的總和;如果提供了 func,那么把前兩個元素傳給它,然后把計算結(jié)果和下一個元素傳給它,以此類推,最后產(chǎn)出結(jié)果
(內(nèi)置)enumerate(iterable, start=0)產(chǎn)出由兩個元素組成的元組,結(jié)構(gòu)是 (index, item),其中 index 從 start 開始計數(shù),item 則從 iterable 中獲取
(內(nèi)置)map(func, it1, [it2, ..., itN])把 it 中的各個元素傳給func,產(chǎn)出結(jié)果;如果傳入 N 個可迭代的對象,那么 func 必須能接受 N 個參數(shù),而且要并行處理各個可迭代的對象

合并多個可迭代對象的生成器函數(shù)

模塊函數(shù)說明
itertoolschain(it1, ..., itN)先產(chǎn)出 it1 中的所有元素,然后產(chǎn)出 it2 中的所有元素,以此類推,無縫連接在一起
itertoolschain.from_iterable(it)產(chǎn)出 it 生成的各個可迭代對象中的元素,一個接一個,無縫連接在一起;it 應(yīng)該產(chǎn)出可迭代的元素,例如可迭代的對象列表
(內(nèi)置)zip(it1, ..., itN)并行從輸入的各個可迭代對象中獲取元素,產(chǎn)出由 N 個元素組成的元組,只要有一個可迭代的對象到頭了,就默默地停止

新的句法:yield from

如果生成器函數(shù)需要產(chǎn)出另一個生成器生成的值, 傳統(tǒng)的方式是嵌套的 for 循環(huán), 例如, 我們要自己實現(xiàn) chain生成器:

可迭代的歸約函數(shù)

有些函數(shù)接受可迭代對象, 但僅返回單個結(jié)果, 這類函數(shù)叫規(guī)約函數(shù).

模塊函數(shù)說明
(內(nèi)置)sum(it, start=0)it 中所有元素的總和,如果提供可選的 start,會把它加上(計算浮點數(shù)的加法時,可以使用 math.fsum 函數(shù)提高精度)
(內(nèi)置)all(it)it 中的所有元素都為真值時返回 True,否則返回 False;all([]) 返回 True
(內(nèi)置)any(it)只要 it 中有元素為真值就返回 True,否則返回 False;any([]) 返回 False
(內(nèi)置)max(it, [key=,] [default=])返回 it 中值最大的元素;*key 是排序函數(shù),與 sorted 函數(shù)中的一樣;如果可迭代的對象為空,返回 default
functoolsreduce(func, it, [initial])把前兩個元素傳給 func,然后把計算結(jié)果和第三個元素傳給 func,以此類推,返回最后的結(jié)果;如果提供了 initial,把它當作第一個元素傳入

第十五章: 上下文管理器和 else 塊

本章討論的是其他語言不常見的流程控制特性, 正因如此, python新手往往忽視或沒有充分使用這些特性. 下面討論的特性有:

  • with 語句和上下文管理器

  • for while try 語句的 else 子句

上下文管理器和with塊

使用@contextmanager

第十六章: 協(xié)程

預(yù)激協(xié)程的裝飾器

協(xié)程內(nèi)部如果不能處理這個異常, 就會導致協(xié)程終止.

第十七章: 使用期物處理并發(fā)

第十八章: 使用 asyncio 包處理并發(fā)

并發(fā)是指一次處理多件事。 并行是指一次做多件事。 二者不同,但是有聯(lián)系。 一個關(guān)于結(jié)構(gòu),一個關(guān)于執(zhí)行。 并發(fā)用于制定方案,用來解決可能(但未必)并行的問題?!?Rob Pike Go 語言的創(chuàng)造者之一

并行是指兩個或者多個事件在同一時刻發(fā)生, 而并發(fā)是指兩個或多個事件在同一時間間隔發(fā)生. 真正運行并行需要多個核心, 現(xiàn)在筆記本一般有 4 個 CPU 核心, 但是通常就有超過 100 個進程同時運行. 因此, 實際上大多數(shù)進程都是并發(fā)處理的, 而不是并行處理. 計算機始終運行著 100 多個進程, 確保每個進程都有機會取得發(fā)展, 不過 CPU 本身同時做的事情不會超過四件.

從期物、任務(wù)和協(xié)程中產(chǎn)出

避免阻塞型調(diào)用

有兩種方法能避免阻塞型調(diào)用中止整個應(yīng)用程序的進程:

  • 在單獨的線程中運行各個阻塞型操作

  • 把每個阻塞型操作轉(zhuǎn)換成非阻塞的異步調(diào)用使用

多線程是可以的, 但是會消耗比較大的內(nèi)存. 為了降低內(nèi)存的消耗, 通常使用回調(diào)來實現(xiàn)異步調(diào)用. 這是一種底層概念, 類似所有并發(fā)機制中最古老最原始的那種--硬件中斷. 使用回調(diào)時, 我們不等待響應(yīng), 而是注冊一個函數(shù), 在發(fā)生某件事時調(diào)用. 這樣, 所有的調(diào)用都是非阻塞的.

異步應(yīng)用程序底層的事件循環(huán)能依靠基礎(chǔ)設(shè)置的中斷, 線程, 輪詢和后臺進程等待等, 確保多個并發(fā)請求能取得進展并最終完成, 這樣才能使用回調(diào). 事件循環(huán)獲得響應(yīng)后, 會回過頭來調(diào)用我們指定的回調(diào). 如果做法正確, 事件循環(huán)和應(yīng)用代碼公共的主線程絕不會阻塞.

把生成器當做協(xié)程使用是異步編程的另一種方式. 對事件循環(huán)來說, 調(diào)用回調(diào)與在暫停的協(xié)程上調(diào)用 .send()效果差不多.

覆蓋型與非覆蓋型描述符對比

python存取屬性的方式是不對等的. 通過實例讀取屬性時, 通常返回的是實例中定義的屬性, 但是, 如果實例中沒有指定的屬性, 那么會從獲取類屬性. 而實例中屬性賦值時, 通常會在實例中創(chuàng)建屬性, 根本不影響類.

覆蓋型描述符

我們要做一個在運行時創(chuàng)建類的, 類工廠函數(shù):

元類基礎(chǔ)知識

元類是制造類的工廠, 不過不是函數(shù), 本身也是類. 元類是用于構(gòu)建類的類 .

謝謝大家閱讀,謝謝“棲遲於一丘”的分享!超牛逼!原文鏈接


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
@所有人,您有一份Python入門基礎(chǔ)學習寶典,請注意查收
Python入門教程:內(nèi)置函數(shù)—Map、Reduce、Filter
第九章:魔法方法、屬性和迭代器
適合Java開發(fā)者學習的Python入門教程
Python 工匠:容器的門道
編程語言Python代碼閱讀(第8篇):列表元素邏輯判斷
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服