Python設(shè)計方法有哪些-創(chuàng)新互聯(lián)

這篇文章主要介紹“Python設(shè)計方法有哪些”,在日常操作中,相信很多人在Python設(shè)計方法有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python設(shè)計方法有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)服務(wù)項目包括句容網(wǎng)站建設(shè)、句容網(wǎng)站制作、句容網(wǎng)頁制作以及句容網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,句容網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到句容省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

15. 為什么 CPython 不使用更傳統(tǒng)的垃圾回收方案?

首先,這不是 C 標(biāo)準(zhǔn)特性,因此不能移植。(是的,我們知道 Boehm GC 庫。它包含了 大多數(shù) 常見平臺(但不是所有平臺)的匯編代碼,盡管它基本上是透明的,但也不是完全透明的; 要讓 Python 使用它,需要使用補丁。)

當(dāng) Python 嵌入到其他應(yīng)用程序中時,傳統(tǒng)的 GC 也成為一個問題。在獨立的 Python 中,可以用 GC 庫提供的版本替換標(biāo)準(zhǔn)的 malloc()和 free(),嵌入 Python 的應(yīng)用程序可能希望用 它自己 替代 malloc()和 free(),而可能不需要 Python 的?,F(xiàn)在,CPython 可以正確地實現(xiàn) malloc()和 free()。

16. CPython 退出時為什么不釋放所有內(nèi)存?

當(dāng) Python 退出時,從全局命名空間或 Python 模塊引用的對象并不總是被釋放。如果存在循環(huán)引用,則可能發(fā)生這種情況 C 庫分配的某些內(nèi)存也是不可能釋放的(例如像 Purify 這樣的工具會抱怨這些內(nèi)容)。但是,Python 在退出時清理內(nèi)存并嘗試銷毀每個對象。

如果要強制 Python 在釋放時刪除某些內(nèi)容,請使用 atexit 模塊運行一個函數(shù),強制刪除這些內(nèi)容。

17. 為什么有單獨的元組和列表數(shù)據(jù)類型?

雖然列表和元組在許多方面是相似的,但它們的使用方式通常是完全不同的。可以認(rèn)為元組類似于 Pascal 記錄或 C 結(jié)構(gòu);它們是相關(guān)數(shù)據(jù)的小集合,可以是不同類型的數(shù)據(jù),可以作為一個組進(jìn)行操作。例如,笛卡爾坐標(biāo)適當(dāng)?shù)乇硎緸閮蓚€或三個數(shù)字的元組。

另一方面,列表更像其他語言中的數(shù)組。它們傾向于持有不同數(shù)量的對象,所有對象都具有相同的類型,并且逐個操作。例如, os.listdir('.') 返回表示當(dāng)前目錄中的文件的字符串列表。如果向目錄中添加了一兩個文件,對此輸出進(jìn)行操作的函數(shù)通常不會中斷。

元組是不可變的,這意味著一旦創(chuàng)建了元組,就不能用新值替換它的任何元素。列表是可變的,這意味著您始終可以更改列表的元素。只有不變元素可以用作字典的 key,因此只能將元組和非列表用作 key。

18. 列表如何在 CPython 中實現(xiàn)?

CPython 的列表實際上是可變長度的數(shù)組,而不是 lisp 風(fēng)格的鏈表。該實現(xiàn)使用對其他對象的引用的連續(xù)數(shù)組,并在列表頭結(jié)構(gòu)中保留指向該數(shù)組和數(shù)組長度的指針。

這使得索引列表 a[i] 的操作成本與列表的大小或索引的值無關(guān)。

當(dāng)添加或插入項時,將調(diào)整引用數(shù)組的大小。并采用了一些巧妙的方法來提高重復(fù)添加項的性能; 當(dāng)數(shù)組必須增長時,會分配一些額外的空間,以便在接下來的幾次中不需要實際調(diào)整大小。

19. 字典如何在 CPython 中實現(xiàn)?

CPython 的字典實現(xiàn)為可調(diào)整大小的哈希表。與 B-樹相比,這在大多數(shù)情況下為查找(目前最常見的操作)提供了更好的性能,并且實現(xiàn)更簡單。

字典的工作方式是使用 hash() 內(nèi)置函數(shù)計算字典中存儲的每個鍵的 hash 代碼。hash 代碼根據(jù)鍵和每個進(jìn)程的種子而變化很大;例如,"Python" 的 hash 值為-539294296,而"python"(一個按位不同的字符串)的 hash 值為 1142331976。然后,hash 代碼用于計算內(nèi)部數(shù)組中將存儲該值的位置。假設(shè)您存儲的鍵都具有不同的 hash 值,這意味著字典需要恒定的時間 -- O(1),用 Big-O 表示法 -- 來檢索一個鍵。

20. 為什么字典 key 必須是不可變的?

字典的哈希表實現(xiàn)使用從鍵值計算的哈希值來查找鍵。如果鍵是可變對象,則其值可能會發(fā)生變化,因此其哈希值也會發(fā)生變化。但是,由于無論誰更改鍵對象都無法判斷它是否被用作字典鍵值,因此無法在字典中修改條目。然后,當(dāng)你嘗試在字典中查找相同的對象時,將無法找到它,因為其哈希值不同。如果你嘗試查找舊值,也不會找到它,因為在該哈希表中找到的對象的值會有所不同。

如果你想要一個用列表索引的字典,只需先將列表轉(zhuǎn)換為元組;用函數(shù) tuple(L)創(chuàng)建一個元組,其條目與列表 L相同。元組是不可變的,因此可以用作字典鍵。

已經(jīng)提出的一些不可接受的解決方案:

  • 哈希按其地址(對象 ID)列出。這不起作用,因為如果你構(gòu)造一個具有相同值的新列表,它將無法找到;例如:

mydict = {[1, 2]: '12'}
print(mydict[[1, 2]])
  • 會引發(fā)一個 KeyError 異常,因為第二行中使用的 [1, 2] 的 id 與第一行中的 id 不同。換句話說,應(yīng)該使用 == 來比較字典鍵,而不是使用is 。

  • 使用列表作為鍵時進(jìn)行復(fù)制。這沒有用的,因為作為可變對象的列表可以包含對自身的引用,然后復(fù)制代碼將進(jìn)入無限循環(huán)。

  • 允許列表作為鍵,但告訴用戶不要修改它們。當(dāng)你意外忘記或修改列表時,這將產(chǎn)生程序中的一類難以跟蹤的錯誤。它還使一個重要的字典不變量無效:d.keys() 中的每個值都可用作字典的鍵。

  • 將列表用作字典鍵后,應(yīng)標(biāo)記為其只讀。問題是,它不僅僅是可以改變其值的頂級對象;你可以使用包含列表作為鍵的元組。將任何內(nèi)容作為鍵關(guān)聯(lián)到字典中都需要將從那里可到達(dá)的所有對象標(biāo)記為只讀 —— 并且自引用對象可能會導(dǎo)致無限循環(huán)。

如果需要,可以使用以下方法來解決這個問題,但使用它需要你自擔(dān)風(fēng)險:你可以將一個可變結(jié)構(gòu)包裝在一個類實例中,該實例同時具有 __eq__() 和 __hash__() 方法。然后,你必須確保駐留在字典(或其他基于 hash 的結(jié)構(gòu))中的所有此類包裝器對象的哈希值在對象位于字典(或其他結(jié)構(gòu))中時保持固定。

class ListWrapper:
 def __init__(self, the_list):
 self.the_list = the_list
 def __eq__(self, other):
 return self.the_list == other.the_list
 def __hash__(self):
 l = self.the_list
 result = 98767 - len(l)*555
 for i, el in enumerate(l):
 try:
 result = result + (hash(el) % 9999999) * 1001 + i
 except Exception:
 result = (result % 7777777) + i * 333
 return result

注意,哈希計算由于列表的某些成員可能不可用以及算術(shù)溢出的可能性而變得復(fù)雜。

此外,必須始終如此,如果 o1 == o2 (即 o1.__eq__(o2) is True )則 hash(o1) == hash(o2)``(即``o1.__hash__() == o2.__hash__() ),無論對象是否在字典中。如果你不能滿足這些限制,字典和其他基于 hash 的結(jié)構(gòu)將會出錯。

對于 ListWrapper ,只要包裝器對象在字典中,包裝列表就不能更改以避免異常。除非你準(zhǔn)備好認(rèn)真考慮需求以及不正確地滿足這些需求的后果,否則不要這樣做。請留意。

21. 為什么 list.sort() 沒有返回排序列表?

在性能很重要的情況下,僅僅為了排序而復(fù)制一份列表將是一種浪費。因此, list.sort() 對列表進(jìn)行了適當(dāng)?shù)呐判?。為了提醒您這一事實,它不會返回已排序的列表。這樣,當(dāng)您需要排序的副本,但也需要保留未排序的版本時,就不會意外地覆蓋列表。

如果要返回新列表,請使用內(nèi)置 sorted() 函數(shù)。此函數(shù)從提供的可迭代列表中創(chuàng)建新列表,對其進(jìn)行排序并返回。例如,下面是如何迭代遍歷字典并按 keys 排序:

for key in sorted(mydict):
 ... # do whatever with mydict[key]...

22. 如何在 Python 中指定和實施接口規(guī)范?

由 C++和 Java 等語言提供的模塊接口規(guī)范描述了模塊的方法和函數(shù)的原型。許多人認(rèn)為接口規(guī)范的編譯時強制執(zhí)行有助于構(gòu)建大型程序。

Python 2.6 添加了一個 abc 模塊,允許定義抽象基類 (ABCs)。然后可以使用isinstance() 和 issubclass() 來檢查實例或類是否實現(xiàn)了特定的 ABC。collections.abc 模塊定義了一組有用的 ABCs 例如 Iterable , Container , 和 MutableMapping

對于 Python,通過對組件進(jìn)行適當(dāng)?shù)臏y試規(guī)程,可以獲得接口規(guī)范的許多好處。還有一個工具 PyChecker,可用于查找由于子類化引起的問題。

一個好的模塊測試套件既可以提供回歸測試,也可以作為模塊接口規(guī)范和一組示例。許多 Python 模塊可以作為腳本運行,以提供簡單的“自我測試”。即使是使用復(fù)雜外部接口的模塊,也常??梢允褂猛獠拷涌诘暮唵巍皹洞a(stub)”模擬進(jìn)行隔離測試。可以使用 doctest 和 unittest 模塊或第三方測試框架來構(gòu)造詳盡的測試套件,以運行模塊中的每一行代碼。

適當(dāng)?shù)臏y試規(guī)程可以幫助在 Python 中構(gòu)建大型的、復(fù)雜的應(yīng)用程序以及接口規(guī)范。事實上,它可能會更好,因為接口規(guī)范不能測試程序的某些屬性。例如,append() 方法將向一些內(nèi)部列表的末尾添加新元素;接口規(guī)范不能測試您的 append() 實現(xiàn)是否能夠正確執(zhí)行此操作,但是在測試套件中檢查這個屬性是很簡單的。

編寫測試套件非常有用,您可能希望設(shè)計代碼時著眼于使其易于測試。一種日益流行的技術(shù)是面向測試的開發(fā),它要求在編寫任何實際代碼之前,首先編寫測試套件的各個部分。當(dāng)然,Python 允許您草率行事,根本不編寫測試用例。

23. 為什么沒有 goto?

可以使用異常捕獲來提供 “goto 結(jié)構(gòu)” ,甚至可以跨函數(shù)調(diào)用工作的 。許多人認(rèn)為異常捕獲可以方便地模擬 C,F(xiàn)ortran 和其他語言的 "go" 或 "goto" 結(jié)構(gòu)的所有合理用法。例如:

class label(Exception): pass # declare a label
try:
 ...
 if condition: raise label() # goto label
 ...
except label: # where to goto
 pass
...

但是不允許你跳到循環(huán)的中間,這通常被認(rèn)為是濫用 goto。謹(jǐn)慎使用。

24. 為什么原始字符串(r-strings)不能以反斜杠結(jié)尾?

更準(zhǔn)確地說,它們不能以奇數(shù)個反斜杠結(jié)束:結(jié)尾處的不成對反斜杠會轉(zhuǎn)義結(jié)束引號字符,留下未結(jié)束的字符串。

原始字符串的設(shè)計是為了方便想要執(zhí)行自己的反斜杠轉(zhuǎn)義處理的處理器(主要是正則表達(dá)式引擎)創(chuàng)建輸入。此類處理器將不匹配的尾隨反斜杠視為錯誤,因此原始字符串不允許這樣做。反過來,允許通過使用引號字符轉(zhuǎn)義反斜杠轉(zhuǎn)義字符串。當(dāng) r-string 用于它們的預(yù)期目的時,這些規(guī)則工作的很好。

如果您正在嘗試構(gòu)建 Windows 路徑名,請注意所有 Windows 系統(tǒng)調(diào)用都使用正斜杠:

f = open("/mydir/file.txt") # works fine!

如果您正在嘗試為 DOS 命令構(gòu)建路徑名,請嘗試以下示例

dir = r"\this\is\my\dos\dir" "\\"
dir = r"\this\is\my\dos\dir\ "[:-1]
dir = "\\this\\is\\my\\dos\\dir\\"

25. 為什么 Python 沒有屬性賦值的“with”語句?

Python 有一個 'with' 語句,它封裝了塊的執(zhí)行,在塊的入口和出口調(diào)用代碼。有些語言的結(jié)構(gòu)是這樣的:

with obj:
 a = 1 # equivalent to obj.a = 1
 total = total + 1 # obj.total = obj.total + 1

在 Python 中,這樣的結(jié)構(gòu)是不明確的。

其他語言,如 ObjectPascal、Delphi 和 C++ 使用靜態(tài)類型,因此可以毫不含糊地知道分配給什么成員。這是靜態(tài)類型的要點 -- 編譯器 總是 在編譯時知道每個變量的作用域。

Python 使用動態(tài)類型。事先不可能知道在運行時引用哪個屬性??梢詣討B(tài)地在對象中添加或刪除成員屬性。這使得無法通過簡單的閱讀就知道引用的是什么屬性:局部屬性、全局屬性還是成員屬性?

例如,采用以下不完整的代碼段:

def foo(a):
 with a:
 print(x)

該代碼段假設(shè) "a" 必須有一個名為 "x" 的成員屬性。然而,Python 中并沒有告訴解釋器這一點。假設(shè) "a" 是整數(shù),會發(fā)生什么?如果有一個名為 "x" 的全局變量,它是否會在 with 塊中使用?如您所見,Python 的動態(tài)特性使得這樣的選擇更加困難。

然而,Python 可以通過賦值輕松實現(xiàn) "with" 和類似語言特性(減少代碼量)的主要好處。代替:

function(args).mydict[index][index].a = 21
function(args).mydict[index][index].b = 42
function(args).mydict[index][index].c = 63

寫成這樣:

ref = function(args).mydict[index][index]
ref.a = 21
ref.b = 42
ref.c = 63

這也具有提高執(zhí)行速度的副作用,因為 Python 在運行時解析名稱綁定,而第二個版本只需要執(zhí)行一次解析。

26. 為什么 if/while/def/class 語句需要冒號?

冒號主要用于增強可讀性(ABC 語言實驗的結(jié)果之一)??紤]一下這個:

if a == b
 print(a)

if a == b:
 print(a)

注意第二種方法稍微容易一些。請進(jìn)一步注意,在這個 FAQ 解答的示例中,冒號是如何設(shè)置的;這是英語中的標(biāo)準(zhǔn)用法。

另一個次要原因是冒號使帶有語法突出顯示的編輯器更容易工作;他們可以尋找冒號來決定何時需要增加縮進(jìn),而不必對程序文本進(jìn)行更精細(xì)的解析。

27. 為什么 Python 在列表和元組的末尾允許使用逗號?

Python 允許您在列表,元組和字典的末尾添加一個尾隨逗號:

[1, 2, 3,]
('a', 'b', 'c',)
d = {
 "A": [1, 5],
 "B": [6, 7], # last trailing comma is optional but good style
}

有幾個理由允許這樣做。

如果列表,元組或字典的字面值分布在多行中,則更容易添加更多元素,因為不必記住在上一行中添加逗號。這些行也可以重新排序,而不會產(chǎn)生語法錯誤。

不小心省略逗號會導(dǎo)致難以診斷的錯誤。例如:

x = [
 "fee",
 "fie"
 "foo",
 "fum"
]

這個列表看起來有四個元素,但實際上包含三個 : "fee", "fiefoo" 和 "fum" ??偸羌由隙禾柨梢员苊膺@個錯誤的來源。

允許尾隨逗號也可以使編程代碼更容易生成。

到此,關(guān)于“Python設(shè)計方法有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

網(wǎng)站欄目:Python設(shè)計方法有哪些-創(chuàng)新互聯(lián)
標(biāo)題路徑:http://muchs.cn/article40/ceejho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、App開發(fā)、全網(wǎng)營銷推廣、關(guān)鍵詞優(yōu)化、Google微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)