B篇,主要介紹Python的自定義函數,匿名函數,面向對象,模塊化。 由於不涉及基礎的知識,我會將重難點加以解釋。 ...
開發|Python核心技術B
B篇,主要介紹Python的自定義函數,匿名函數,面向對象,模塊化。
由於不涉及基礎的知識,我會將重難點加以解釋。
前言
目前所有的文章思想格式都是:知識+情感。
知識:對於所有的知識點的描述。力求不含任何的自我感情色彩。
情感:用我自己的方式,解讀知識點。力求通俗易懂,完美透析知識。
正文
談談自定義函數
談談匿名函數
談談面向對象
談談模塊化
談談自定義函數
對於,如何自定義一個函數,我覺得應該不需要介紹了,在之前的淺談Python函數文章中,有詳細的介紹。
問題:函數的參數有哪幾種?
答:位置參數,預設參數,關鍵字參數,非固定參數。
Python 中函數的參數可以接受任意的數據類型,使用起來需要註意,必要時請在函數開頭加入數據類型的檢查。
問題:Python的函數名可以當成參數使用嗎?
答:可以,直接傳遞函數名字,加上括弧之後就可以調用該函數。
問題:函數嵌套之後,變數的作用域查找順序是什麼樣子的?
答:遵循LEGB順序,首先會在local尋找,其次會在嵌套域找,接著會在全局尋找,最後會在內置變數找,找不到就報錯,NameError。
嵌套函數的使用,能保證數據的隱私性,提高程式運行效率。
問題:nonelocal與global的區別?
答:對於嵌套函數來說,內部函數可以訪問外部函數定義的變數,但是無法修改,若要修改,必須加上 nonlocal 這個關鍵字。
如果使用 global,就會直接聲明函數內部的變數就是全局的那個同名變數。
問題:閉包(closure)是什麼?
答:閉包表示在嵌套函數中,外部函數返回內部函數的函數名,內部函數引用外部函數的變數。
閉包函數返回的值,可以加括弧直接調用。使用閉包的一個原因,是讓程式變得更簡潔易讀。
談談匿名函數(lambda)
問題:為什麼使用匿名函數?
答:運用匿名函數,能讓我們的代碼更簡潔、易讀。
問題:匿名函數是什麼?
答:lambda 是一個表達式(expression),並不是一個語句(statement).lambda 的主體是只有一行的簡單表達式,並不能擴展成一個多行的代碼塊。
所謂的表達式,就是用一系列“公式”去表達一個東西,比如x + 2、 x**2等等;
而所謂的語句,則一定是完成了某些功能,比如賦值語句x = 1完成了賦值,print 語句print(x)完成了列印,條件語句 if x < 0:完成了選擇功能等等。
lambda 專註於簡單的任務,而常規函數則負責更複雜的多行邏輯。
問題:lambda的應用場景?
答:lambda可以結合列表生成式一起使用。
s = [(lambda x: x+1) (x) for x in range(10)]
s
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
lamba可以和內置函數一起使用,如reduce(), sort(),filter()。
m = filter(lambda x: x >7, [1, 4, 5, 6, 9, 33, 22])
m
<filter object at 0x000002A0FA605E80>
list(m)
[9, 33, 22]
問題:什麼是函數式編程?
答: 所謂函數式編程,是指代碼中每一塊都是不可變的(immutable),都由純函數(pure function)的形式組成。這裡的純函數,是指函數本身相互獨立、互不影響,對於相同的輸入,總會有相同的輸出,沒有任何副作用。
函數式編程的優點,主要在於其純函數和不可變的特性使程式更加健壯,易於調試(debug)和測試;缺點主要在於限制多,難寫。
問題:什麼是map()?
答:map(function, iterable) 函數,它表示,對 iterable 中的每個元素,都運用 function 這個函數,最後返回一個新的可遍歷的集合。結合lambda使用。
map函數,for 迴圈和 list comprehension,一起創建列表,最終map() 是最快的。因為 map() 函數直接由 C 語言寫的,運行時不需要通過 Python 解釋器間接調用,並且內部做了諸多優化,所以運行速度最快。
問題:什麼是filter()?
答: filter(function, iterable) 函數,它和 map 函數類似,function 同樣表示一個函數對象。filter() 函數表示對 iterable 中的每個元素,都使用 function 判斷,並返回 True 或者 False,最後將返回 True 的元素組成一個新的可遍歷的集合。
問題:什麼是reduse()?
答: reduce(function, iterable) 函數,它通常用來對一個集合做一些累積操作。function 同樣是一個函數對象,規定它有兩個參數,表示對 iterable 中的每個元素以及上一次調用後的結果,運用 function 進行計算,所以最後返回的是一個單獨的數值。
談談面向對象
引入: 談面向對象,必然會引入面向過程,而面向過程的基本單位是函數,面向對象的基本單位就是類。
問題:Python中的類是什麼?
答: 類,是一群有著相同屬性和函數的對象的集合。
**問題: __ init __函數的作用?**
答:在對象生成的時候,自動調用__ init __函數,構造當前對象的屬性。init表示構造函數,不知道你還記得初始化git倉庫不~
問題:如何在一個類中定義一些常量,每個對象都可以方便訪問這些常量而不用重新構造?
答:可以直接書寫類的屬性,可以供類自己調用,每一個實例化對象調用。
問題:如果一個函數不涉及到訪問修改這個類的屬性,而放到類外面有點不恰當,怎麼做才能更優雅呢?
答: 使用類的封裝性,使用雙下劃線,表示為類的私有屬性,只能內部調用。其實外部也可以調用,只是需要變一種格式,_類名__屬性名。
針對於方法,可以使用裝飾器添加給類的@classmethod,也可以屬於靜態函數,相當於普通函數,使用裝飾器加上@staticmethod。
問題:既然類是一群相似的對象的集合,那麼可不可以是一群相似的類的集合呢?
答:可以,使用類的繼承特性,子類可以繼承父類。繼承關係使用mro表存儲。
註意:繼承的查找順序,一定是自己對象有的,就在對象找,找不到去類找,再找不到按照mro繼承表順序查找。
問題:繼承的super()使用場景?
答:super可以重用父類的方法和屬性,是的代碼重用。
問題:抽象類有什麼用途?
答:抽象類,from abc import ABCMeta, abstractmethod
抽象類可以定義介面,要求繼承者必須實現當前介面,不然就會報錯。
大型工程往往需要很多人合作開發,在 idea 提出之後,開發組和產品組首先會召開產品設計會,PM(Product Manager,產品經理) 寫出產品需求文檔,然後迭代;TL(Team Leader,項目經理)編寫開發文檔,開發文檔中會定義不同模塊的大致功能和介面、每個模塊之間如何協作、單元測試和集成測試、線上灰度測試、監測和日誌等等一系列開發流程。
問題:什麼是面向對象編程?
答:面向對象編程是軟體工程中重要的思想。正如動態規劃是演算法中的重要思想一樣,它不是某一種非常具體的技術,而是一種綜合能力的體現,是將大型工程解耦化、模塊化的重要方法。在實踐中要多想,尤其是抽象地想,才能更快掌握這個技巧。
談談模塊化
問題:模塊化可以解決什麼問題?
答:模塊化,可以很方便的對代碼進行解耦,化繁為簡,只需要調用即可實現。後期的配置,更改更為簡單。
問題:引入模塊的方式?
答:可以使用: from xx import xx 或者 import xxx
**問題:__ init__.py文件是什麼?**
答:在模塊所在的文件夾新建一個 init.py,內容可以為空,也可以用來表述包對外暴露的模塊介面。
實上,這是 Python 2 的規範。在 Python 3 規範中,init.py 並不是必須的。
問題:如何將項目模塊化?
答:雖然運行 sys.path.append("..") ,則可以改變當前 Python 解釋器的位置,但是不要使用。
在大型工程中儘可能使用絕對位置是第一要義。對於一個獨立的項目,所有的模塊的追尋方式,最好從項目的根目錄開始追溯,這叫做相對的絕對路徑。
以項目的根目錄作為最基本的目錄,所有的模塊調用,都要通過根目錄一層層向下索引的方式來 import。
問題:sys.path列表表示什麼?
答:Python 解釋器在遇到 import 的時候,它會在一個sys.path的列表中尋找模塊。所以,sys.path 表示的是Python執行程式導入包的查找路徑。
它的第一項為空,第一項設置為項目根目錄的絕對地址。
問題:項目的包一半如何管理?
答:使用Python 的 Virtual Environment(虛擬運行環境)。Python 可以通過 Virtualenv 工具,非常方便地創建一個全新的 Python 運行環境。
對於每一個項目來說,最好要有一個獨立的運行環境來保持包和模塊的純凈性。
問題:if name == 'main' 是什麼意思?
答: name 作為 Python 的魔術內置參數,本質上是模塊對象的一個屬性。我們使用 import 語句時,name 就會被賦值為該模塊的名字,自然就不等於 __main__了。
所以,import 在導入文件的時候,會自動把所有暴露在外面的代碼全都執行一遍,而在if name == 'main' 內部的代碼不會被執行。
註意: import 模塊的時候,會執行該模塊,所以最終執行的代碼是在該文件下的文件加上所有導入的代碼。(可以適當幻想一下~)
結束語
Python的核心技術B,主要是函數與對象的知識,外加講解了自定義函數與匿名函數,模塊化。
希望大家,可以在書寫項目的時候,巧用模塊化思想,面向對象思想~