python提高知識點
python提高
1 全局解釋器鎖(GIL)---不是python的特性
描述Python GIL的概念, 以及它對python多線程的影響?編寫一個多線程抓取網頁的程序,並闡明多線程抓取程序是否可比單線程性能有提升,並解釋原因。
1. Python語言和GIL沒有任何關系。僅僅是由於歷史原因在Cpython虛擬機(解釋器),難以移除GIL。(java編寫的python解釋器不存在這個問題)
2. GIL:全局解釋器鎖。每個線程在執行的過程都需要先獲取GIL,保證同一時刻只有一個線程可以執行代碼。
3. 線程釋放GIL鎖的情況: 遇到IO阻塞時,可以暫時釋放GIL
4. Python使用多進程是可以利用多核的CPU資源的。
5. 多線程爬取比單線程性能有提升,因為遇到IO阻塞會自動釋放GIL鎖
解決GIL的兩種方法:使用其他語言編寫的解釋器、使用其他語言編寫多線程、使用多進程
2 io 密集型和 cpu 密集型區別
io 密集型:系統運作,大部分的狀況是 CPU 在等 I/O (硬盤/內存) 的讀/ 寫
Cpu 密集型:大部份時間用來做計算、邏輯判斷等 CPU 動作的程序稱之 CPU 密集型
3 深拷貝和淺拷貝
淺拷貝:拷貝最頂層的數據給新的對象,只是拷貝了引用
深拷貝:拷貝對象及其內部的對象
切片、字典拷貝和copy.copy()
註意點
對不可變類型和可變類型的copy不同:
1. copy.copy對於可變類型,會進行淺拷貝。
2. copy.copy對於不可變類型,不會拷貝,僅僅是指向。
3. copy.deepcopy對於全部是不可變類型的數據,也不會拷貝,僅僅是指向
copy.copy和copy.deepcopy的區別。
1.copy.copy 淺拷貝 只拷貝父對象,不會拷貝對象的內部的子對象
2.copy.deepcopy 深拷貝 拷貝對象及其子對象
4 私有化
xx: 公有變量
_x: 單前置下劃線,私有化屬性或方法,from 模塊 import *禁止導入,類對象和子類可以訪問。
__xx:雙前置下劃線,私有化屬性或方法,避免與子類中的屬性命名沖突,無法在外部直接訪問(名字重整所以訪問不到,_類名__xx)
__xx__:雙前後下劃線,用戶名字空間的魔法對象或屬性。例如:__init__ , __ 不要自己發明這樣的名字。
xx_:單後置下劃線,用於避免與Python關鍵詞的沖突,不推薦使用。
5 模塊搜索順序
import sys # 導入模塊
sys.path # 返回查找模塊的列表目錄,列表中的路徑的先後順序代表了python解釋器在搜索模塊時的先後順序。第一個元素返回的是一個空字符串表示當前目錄。
sys.path.append(‘/home/itcast/xxx‘) # 在列表最後追加搜索目錄
sys.path.insert(0, ‘/home/itcast/xxx‘) # 可以確保先搜索這個路徑
6 重新導入模塊
from imp import reload
reaload(模塊名)
(必須得先import 模塊)
7 多模塊開發時註意事項
通過from 模塊 import 變量,此時相當於給一個變量賦值,如果在程序中修改了變量的值就導致這個變量成了局部變量,跟其他模塊就不共享了。如果多模塊開發時想導入變量,建議使用import 模塊名的方式,然後通過模塊名.變量的方式去調用。
模塊導入順序:python標準庫、第三方庫、自定義模塊
8 繼承、封裝和多態
封裝就是把方法和屬性封裝到類的內部,只需要在類的外部,通過對象即可調用。繼承實現了代碼的重用。子類可以繼承父類,並且可以繼承多個父類即多繼承,子類可以使用父類所擁有的屬性和方法(除了私有屬性和方法)。多態是以繼承和重寫父類方法為前提,增加了代碼的靈活度,只是一種調用技巧。
9 多繼承和MRO順序
多繼承是指子類繼承了多個父類,可以通過三種方法調用父類的方法:
1. 父類.父類中的方法(self):這種方法容易造成父類中的方法被多次調用,而且父類中的方法一旦改變子類中的方法也要改變。
2. super(指定某個類名, self).父類方法():從指定類名的MRO順序下一級開始調用。
3. super().父類中方法():從當前類的mro順序開始調用父類中方法。
mro:方法解析順序 Method Resolution Order
通過class.__mro__查看當前類的mro調用順序
說明:
單繼承使用哪一種方法都可以,基本上無差別,但是建議使用super()方法。單繼承中只需要傳父類參數,多繼承需要傳全部的參數。
10 類屬性和實例屬性的區別
類是有個特殊的對象即類對象,描述類的特性的是類屬性,類屬性在初始化方法(init)之外定義的,實例對象所共有,類屬性在內存中只有一份。
實例屬性在init方法之內定義的,是實例對象所獨有的,在各自的內存中保存,由對象去訪問。
11 實例方法、類方法和靜態方法的區別
1. 這三種方法都封裝在類的內部,調用者不同。
2. 實例方法是由實例對象調用,至少有一個參數self
3. 類方法是由類對象調用,類方法需要classmothed修飾器修飾。
4. 靜態方法由類對象調用,不需要參數,需要staticmothed修飾器修飾。
註意:區別從調用者、參數和是否需要修飾器修飾三個方面入手
12 property屬性
property屬性:一種用來像是使用實例屬性一樣的特殊屬性,可以應用於某個方法。
註意:
1. 在實例方法的基礎上,通過property修飾器修飾,只有一個參數self
2. 獲取property屬性,不能加括號,加上會報錯。
實現property屬性的兩種方法:修飾器、類屬性
修飾器:經典類中,只有property修飾器即@property。新式類有三類即@property、@方法.setter、@方法.deleter,分別是取值、修改、刪除。
類屬性:通過類屬性實現property屬性時,經典類和新式類無差別,property()中有四個參數,前三個是方法(取值、修改、刪除),第四個參數是字符串
property方法中有個四個參數:
第一個參數是方法名,調用 對象.屬性 時自動觸發執行方法
第二個參數是方法名,調用 對象.屬性 = XXX 時自動觸發執行方法
第三個參數是方法名,調用 del 對象.屬性 時自動觸發執行方法
第四個參數是字符串,調用 對象.屬性.__doc__ ,此參數是該屬性的描述信息
13 常見的魔方屬性、方法
__doc__ 表示類的描述信息
__module__ 表示當前操作的對象在那個模塊
__class__ 表示當前操作的對象的類是什麽
__new__ 創建對象時為對象分配空間,在初始化方法__init__之前被調用
__init__ 初始化方法,通過類創建對象時,自動觸發執行
__del__ 當對象在內存中被釋放時,自動觸發執行
__call__ 對象後面加括號,觸發執行,例如對象()或者類名()()
__dict__ 類或對象中的所有屬性
__str__ 在打印對象時,默認輸出該方法的返回值(自定義字符串)
14 with與上下文管理器
任何實現了 __enter__() 和 __exit__() 方法的對象都可稱之為上下文管理器,上下文管理器對象可以使用 with 關鍵字。
Python 還提供了一個 contextmanager 的裝飾器,更進一步簡化了上下文管理器的實現方式。通過 yield 將函數分割成兩部分,yield 之前的語句在 __enter__ 方法中執行,yield 之後的語句在 __exit__ 方法中執行。緊跟在 yield 後面的值是函數的返回值。
1. 什麽是GIL?GIL對多線程的影響
GIL全稱Global Interpreter Lock(全局解釋器鎖)。GIL和Python語言沒有任何關系,只是因為歷史原因導致在官方推薦的解釋器Cpython中遺留的問題。每個線程在執行的過程中都需要先獲取GIL,保證同一時刻只有一個線程可以執行代碼,但是當遇到IO阻塞會自動的釋放GIL鎖,所以使用多線程還是比單線程的效率要高。如果想發揮多核CPU資源,可以使用多進程。為了避免受GIL的影響可以不用官方推薦的Cpython,或者用其他語言來實現。
計算密集型建議采用進程
IO密集型建議采用線程或者協程
2.深拷貝和淺拷貝
淺拷貝是對一個對象的頂層(外層)拷貝,只是拷貝了引用,並沒有拷貝內容。
變量的賦值是地址的引用,也算是一種淺拷貝。
copy.copy()
深拷貝則是對一個對象深層(遞歸)的拷貝。
copy.deepcopy()
可變類型:列表、字典
不可變類型:數字類型、字符串型、元組
如果是可變類型,淺拷貝只拷貝外層,而深拷貝是完全拷貝
如果是純的不可變類型,那麽無論是淺拷貝還是深拷貝,都只是指向同一個地址。如果不可變類型裏面還存在可變類型,則淺拷貝是指向,而深拷貝則為完全拷貝。
(了解)列表切片、字典的copy方法均屬於淺拷貝
3.私有化
xx: 公有變量
_x: 單前置下劃線,私有化屬性或方法,from 模塊 import *禁止導入,類對象和子類可以訪問。
__xx:雙前置下劃線,避免與子類中的屬性命名沖突,無法在外部直接訪問(名字重整所以訪問不到,_類名__xx)
__xx__:雙前後下劃線,用戶名字空間的魔法對象或屬性。例如:__init__ , __ 不要自己發明這樣的名字。
xx_:單後置下劃線,用於避免與Python關鍵詞的沖突,不推薦使用。
4.模塊搜索順序
import sys
sys.path # 返回查找模塊的列表目錄,列表中的路徑的先後順序代表了python解釋器在搜索模塊時的先後順序。第一個元素返回的是一個空字符串表示當前目錄。
sys.path.append(‘/home/itcast/xxx‘) # 在列表最後追加搜索目錄
sys.path.insert(0, ‘/home/itcast/xxx‘) # 可以確保先搜索這個路徑
5.重新導入模塊
from imp import reload
reaload(模塊名)
(必須得先import 模塊)
6.多模塊開發時註意事項
通過from 模塊 import 變量,此時相當於給一個變量賦值,如果在程序中修改了變量的值就導致這個變量成了局部變量,跟其他模塊就不共享了。如果多模塊開發時想導入變量,建議使用import 模塊名的方式,然後通過模
塊名.變量的方式去調用。
7.面向對象的三大特性(封裝、繼承、多態)
封裝就是把方法和屬性封裝到類的內部,只需要在類的外部,通過對象即可調用。繼承實現了代碼的重用。子類可以繼承父類,並且可以繼承多個父類即多繼承,子類可以使用父類所擁有的屬性和方法(除了私有屬性和方法)。多態是以繼承和重寫父類方法為前提,增加了代碼的靈活度,只是一種調用技巧。
python提高知識點