1、裝飾器:
定義:本質是函數,(裝飾其餘函數)就是爲其餘函數添加附加功能。
原則:1.不能修改被裝飾的函數的源代碼
2.不能修改被裝飾函數的調用方式
實現裝飾器的知識儲備:
1.函數即‘變量’
2.高階函數
a:把一個函數名當作實參傳給另一個函數
b:返回值中包含函數名(不修改函數的調用方式)
3.嵌套函數
高階函數+嵌套函數=》裝飾器python
2、生成器:
經過列表生成式,咱們能夠直接建立一個列表。可是,受到內存限制,列表容量確定是有限的。
並且,建立一個包含100萬個元素的列表,不只佔用很大的存儲空間,若是咱們僅僅須要訪問前面幾個元素,
那後面絕大多數元素佔用的空間都白白浪費了。
因此,若是列表元素能夠按照某種算法推算出來,那咱們是否能夠在循環的過程當中不斷推算出後續的元素呢?
這樣就沒必要建立完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,
稱爲生成器:generator。
若是要一個一個打印出來,能夠經過next()函數得到generator的下一個返回值:
咱們講過,generator保存的是算法,每次調用next(g),就計算出g的下一個元素的值,
直到計算到最後一個元素,沒有更多的元素時,拋出StopIteration的錯誤。
不斷調用next(g)實在是太變態了,正確的方法是使用for循環,由於generator也是可迭代對象
因此,咱們建立了一個generator後,基本上永遠不會調用next(),而是經過for循環來迭代它,而且不須要關心StopIteration的錯誤。
generator很是強大。若是推算的算法比較複雜,用相似列表生成式的for循環沒法實現的時候,還能夠用函數來實現。
定義generator的另外一種方法。若是一個函數定義中包含yield關鍵字,那麼這個函數就再也不是一個普通函數,而是一個generator
這裏,最難理解的就是generator和函數的執行流程不同。函數是順序執行,遇到return語句或者最後一行函數語句就返回。
而變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。
咱們在循環過程當中不斷調用yield,就會不斷中斷。固然要給循環設置一個條件來退出循環,否則就會產生一個無限數列出來。
一樣的,把函數改爲generator後,咱們基本上歷來不會用next()來獲取下一個返回值,而是直接使用for循環來迭代
可是用for循環調用generator時,發現拿不到generator的return語句的返回值。若是想要拿到返回值,
必須捕獲StopIteration錯誤,返回值包含在StopIteration的value中
還可經過yield實如今單線程的狀況下實現併發運算的效果算法
3、迭代器:
咱們已經知道,能夠直接做用於for循環的數據類型有如下幾種:
一類是集合數據類型,如list、tuple、dict、set、str等;
一類是generator,包括生成器和帶yield的generator function。
這些能夠直接做用於for循環的對象統稱爲可迭代對象:Iterable。
可使用isinstance()判斷一個對象是不是Iterable對象flask
而生成器不但能夠做用於for循環,還能夠被next()函數不斷調用並返回下一個值,
直到最後拋出StopIteration錯誤表示沒法繼續返回下一個值了。
*能夠被next()函數調用並不斷返回下一個值的對象稱爲迭代器:Iterator。
可使用isinstance()判斷一個對象是不是Iterator對象
生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。
把list、dict、str等Iterable變成Iterator可使用iter()函數併發
由於Python的Iterator對象表示的是一個數據流,Iterator對象能夠被next()函數調用並不斷返回下一個數據,
直到沒有數據時拋出StopIteration錯誤。能夠把這個數據流看作是一個有序序列,但咱們卻不能提早知道序列的長度,
只能不斷經過next()函數實現按需計算下一個數據,因此Iterator的計算是惰性的,只有在須要返回下一個數據時它纔會計算。
Iterator甚至能夠表示一個無限大的數據流,例如全體天然數。而使用list是永遠不可能存儲全體天然數的。框架
小結
凡是可做用於for循環的對象都是Iterable類型;
凡是可做用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;
集合數據類型如list、dict、str等是Iterable但不是Iterator,不過能夠經過iter()函數得到一個Iterator對象。函數
4、軟件目錄結構規範
"項目目錄結構"其實也是屬於"可讀性和可維護性"的範疇,咱們設計一個層次清晰的目錄結構,就是爲了達到如下兩點:
1.可讀性高: 不熟悉這個項目的代碼的人,一眼就能看懂目錄結構,知道程序啓動腳本是哪一個,測試目錄在哪兒,
配置文件在哪兒等等。從而很是快速的瞭解這個項目。
2.可維護性高: 定義好組織規則後,維護者就能很明確地知道,新增的哪一個文件和代碼應該放在什麼目錄之下。2.
這個好處是,隨着時間的推移,代碼/配置的規模增長,項目結構不會混亂,仍然可以組織良好。工具
目錄組織方式
假設你的項目名爲foo, 我比較建議的最方便快捷目錄結構這樣就足夠了:單元測試
Foo/
|-- bin/
| |-- foo
|
|-- foo/
| |-- tests/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- docs/
| |-- conf.py
| |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README學習
簡要解釋一下:
bin/: 存放項目的一些可執行文件,固然你能夠起名script/之類的也行。
foo/: 存放項目的全部源代碼。(1) 源代碼中的全部模塊、包都應該放在此目錄。不要置於頂層目錄。(2) 其子目錄tests/存放單元測試代碼; (3) 程序的入口最好命名爲main.py。
docs/: 存放一些文檔。
setup.py: 安裝、部署、打包的腳本。
requirements.txt: 存放軟件依賴的外部Python包列表。
README: 項目說明文件。測試
關於README的內容
這個我以爲是每一個項目都應該有的一個文件,目的是能簡要描述該項目的信息,讓讀者快速瞭解這個項目。
它須要說明如下幾個事項:
1.軟件定位,軟件的基本功能。
2.運行代碼的方法: 安裝環境、啓動命令等。
3.簡要的使用說明。
4.代碼目錄結構說明,更詳細點能夠說明軟件的基本原理。
5.常見問題說明。
我以爲有以上幾點是比較好的一個README。在軟件開發初期,因爲開發過程當中以上內容可能不明確或者發生變化,
並非必定要在一開始就將全部信息都補全。可是在項目完結的時候,是須要撰寫這樣的一個文檔的。
關於requirements.txt和setup.py
setup.py
通常來講,用setup.py來管理代碼的打包、安裝、部署問題。業界標準的寫法是用Python流行的打包工具setuptools來管理這些事情。
這種方式廣泛應用於開源項目中。不過這裏的核心思想不是用標準化的工具來解決這些問題,而是說,一個項目必定要有一個安裝部署工具,
能快速便捷的在一臺新機器上將環境裝好、代碼部署好和將程序運行起來。
我剛開始接觸Python寫項目的時候,安裝環境、部署代碼、運行程序這個過程全是手動完成,遇到過如下問題:
安裝環境時常常忘了最近又添加了一個新的Python包,結果一到線上運行,程序就出錯了。
Python包的版本依賴問題,有時候咱們程序中使用的是一個版本的Python包,可是官方的已是最新的包了,經過手動安裝就可能裝錯了。
若是依賴的包不少的話,一個一個安裝這些依賴是很費時的事情。
新同窗開始寫項目的時候,將程序跑起來很是麻煩,由於可能常常忘了要怎麼安裝各類依賴。
setup.py能夠將這些事情自動化起來,提升效率、減小出錯的機率。"複雜的東西自動化,能自動化的東西必定要自動化。"是一個很是好的習慣。
setuptools的文檔比較龐大,剛接觸的話,可能不太好找到切入點。學習技術的方式就是看他人是怎麼用的,能夠參考一下Python的一個Web框架,flask是如何寫的: setup.py
固然,簡單點本身寫個安裝腳本(deploy.sh)替代setup.py也何嘗不可。
requirements.txt
這個文件存在的目的是:
1.方便開發者維護軟件的包依賴。將開發過程當中新增的包添加進這個列表中,避免在setup.py安裝依賴時漏掉軟件包。
2.方便讀者明確項目使用了哪些Python包。
關於配置文件的使用方法
注意,在上面的目錄結構中,沒有將conf.py放在源碼目錄下,而是放在docs/目錄下。
不少項目對配置文件的使用作法是:
配置文件寫在一個或多個python文件中,好比此處的conf.py。
項目中哪一個模塊用到這個配置文件就直接經過import conf這種形式來在代碼中使用配置。
這種作法我不太贊同:
這讓單元測試變得困難(由於模塊內部依賴了外部配置)
另外一方面配置文件做爲用戶控制程序的接口,應當能夠由用戶自由指定該文件的路徑。
程序組件可複用性太差,由於這種貫穿全部模塊的代碼硬編碼方式,使得大部分模塊都依賴conf.py這個文件。
因此,我認爲配置的使用,更好的方式是,
模塊的配置都是能夠靈活配置的,不受外部配置文件的影響。程序的配置也是能夠靈活控制的。