python開發 - 高階知識點總結
一、可迭代物件,迭代器物件和生成器
像list,tuple等這些序列是可以使用for...in...語句進行遍歷輸出的。這是為什麼呢?這就要需要知道可迭代物件(Iterable),迭代器物件(Iterator)和生成器物件(Genertor)。
1、什麼是可迭代物件?
把可以通過for...in...這類語句迭代讀取一條資料提供我們使用的物件。
2、可迭代物件的本質?
可迭代物件通過__iter__方法向我們提供一個迭代器,我們在迭代一個可迭代物件的時候,實際上就是先獲得該物件提供的一個迭代器,然後通過這個迭代器來依次獲取物件中的每一個數據。
也就是說可迭代物件必須要有 __iter__()方法
3、iter()函式和next()函式的作用是什麼?
通過iter()函式獲取可迭代物件的迭代器
然後我們可以對獲取到的迭代器不斷使用next()函式來獲取下一條資料。當我們已經迭代完最後一個數據之後,再次呼叫next()函式會丟擲Stoplteration異常
來告訴我們所有的資料都已經迭代完成,不用再執行mext()函數了
4、什麼是迭代物件?
一個實現了 __iter__ 方法和 __next__ 方法的物件,就是迭代器
5、什麼是生成器?
簡單來說:只要在def中有yield關鍵字的,就是生成器
6、yield的作用是什麼?
yield關鍵字有兩點作用:
(1)儲存當前執行狀態(斷點),然後暫停執行,即將生成器(函式)掛起
(2)將yield關鍵字後面表示式的值作為返回值返回,此時可以理解為起到了return作用
Python2x中的原生協成就是使用yield關鍵字,但在Python3x中使用的是yield from
7、如何啟動生成器?
send():除了能喚醒生成器外,還可以給生成器傳值
next():單純的獲取生成器的一個值
二、GIL
前言:瞭解Python的都知道,在Python中多執行緒並不是真正意義上的多執行緒。那為什麼在Python中多執行緒的威力沒有像其他語言哪有強大呢?
1、GIL全程是全域性直譯器鎖,保證了同一時刻只有一個執行緒在執行。
2、作用:在單核的情況下實現多工!這在當時是非常厲害的技術
3、產生問題的原因:一個CPU分配給一個程序,程序的執行緒是使用GIL進行資源搶奪。在多核情況下,會使其他核空閒,CPU利用率不高。
4、解決方案:
(1)使用其他直譯器,如JPython(但是太慢,不好)。因為只有在CPython中才存在GIL
(2)使用其他語言(c/java)來寫多執行緒這部分程式碼
(3)使用多程序+協成的方式(重點推薦)
三、淺拷貝和深拷貝
深拷貝:它是一種遞迴的方式拷貝某個物件,單獨形成一個新物件。這種方式很浪費資源。
淺拷貝:它只複製一層資訊,佔用的資源少!而且大部分的形式都是淺拷貝。
四、面向物件總結
1、私有化
(1)x:公有變數
(2)_x:單個前置下劃線,私有化方法或屬性,from some_modue import * 是不能匯入的,只有類和物件可以訪問。
(3)__x:雙前置下劃線,避免與子類中的屬性命名衝突,外部無法訪問,但是可以通過特殊的方法訪問到(obj._類名__xx)
(4)__x__:雙前後下劃線,使用者名稱空間的魔法方法後的屬性。最好不要用
(5)x_:單後置下劃線,用於避免與Python關鍵字衝突。
2、封裝
一個功能一個函式,把相關函式封裝成一個類物件。好處是程式碼可以複用。
3、繼承:
多個子類擁有相同的功能,然後把相同的函式放到父類中,通過子類的方式繼承下來。
4、多型:
(1)必須要有繼承
(2)不同物件呼叫同一個函式,會用不同的表現形式
(3)Python中的多型並不是嚴謹的多型,因為沒有做型別檢查。
5、類與例項物件之間的關係:
6、面向函式程式設計和麵向物件程式設計
面向函式程式設計:一個功能一個函式
面向物件程式設計:把相關函式封裝成一個類物件
五、模組匯入與路徑搜尋
1、動態匯入:
(1)import module;
(2) __import__("some_module")
這兩種方式是一樣的
2、路徑搜尋:
在匯入某一個模組時,會在sys.path()中搜索目標模組。如果找到了,那麼就停止搜尋,否則一直找到最後。
3、重新載入模組
from imp import reload , reload 函式的好處是當匯入的某個模組做了修改時,又不想通過關機開重新匯入,而是進行熱更新,就能獲取到修改後的值
六、類中方法總結
1、魔法方法
(1)__init__ :用於初始化物件
(2)__new__:用於建立物件
(3)__call__ :使物件變的可呼叫
(4)__dict__ :把類中的屬性組成一個字典,屬性名作為key,屬性值作為value
(5)__class__:用於檢視物件是由那個類建立的
2、super():
當有多個類發生繼承關係時,Python內部會維護著一張繼承表(通過__mro__可以檢視)super()在當前繼承表中找到自己的位置,然後執行下一個類的__init__方法。
七、上下文管理器(ContextManager)
在很多時候,我們都會看到with open(filename, 'w') as f : pass ,這種操作檔案的方式。這種操作的好處就是我們不需要手動呼叫f.close()來關閉我們開啟的檔案。
任何一個上下文管理器物件都可以使用with關鍵字來操作。
只要實現了 __enter__()和__exit__()方法的類就是上下文管理器
__enter__():返回資源物件
__exit__():在出差完成之後,進行清除工作。如關閉檔案
連線資料庫的上下文管理器:
第一種方式:
from pymysql import connect class DBHelper: def __init__(self): self.conn = connect(host='localhost', port=3306, user='user', password='password', databases='database', charset='utf8') self.csr = self.conn.cursor() def __enter__(self): return self.csr def __exit__(self, exc_type, exc_val, exc_tb): self.csr.close() self.conn.close() with DBHelper() as csr: sql = "select * from table;" csr.execute(sql) all_datas = csr.fetchall() for item in all_datas: print(item)
第二種方式
@contextmanager def conn_db(): conn = connect(host='localhost', port=3306, user='user', password='password', database='database', charset='utf8') csr = conn.cursor() yield csr csr.close() conn.close() with conn_db() as csr: sql = "select * from table;" csr.execute(sql) all_datas = csr.fetchall() for item in all_datas: print(item)