一.Python 中類方法寿烟、類實例方法、靜態(tài)方法有何區(qū)別
定義區(qū)別:
1.類方法和靜態(tài)方法分別有專門的修飾符 @classmethod,@staticmethod碗短。
2.實例方法有self參數(shù)凤优,類方法有cls參數(shù)(類參數(shù))悦陋,靜態(tài)方法是不需要這些附加參數(shù)的
3.靜態(tài)方法實際上跟該類沒有太大關(guān)系
訪問區(qū)別:
- 類和實例都可以訪問靜態(tài)方法和類方法
- 從理論上來說,類是不能訪問實例方法的筑辨,但是可以把實例/類作為參數(shù)傳入俺驶,訪問如下:
a=Myclass()
Myclass.method(a)
Myclass.method(Myclass)
二.Python 中如何動態(tài)獲取和設(shè)置對象的屬性
hasattr,setattr,getattr
三.Python 的內(nèi)存管理機制及調(diào)優(yōu)手段
點這里[http://www.reibang.com/p/6e82c7a54c33]
內(nèi)存泄漏:有 del() 函數(shù)的對象間的循環(huán)引用是導(dǎo)致內(nèi)存泄漏的主兇。
不使用一個對象時使用:del object 來刪除一個對象的引用計數(shù)就可以有效防止內(nèi)存泄漏問題棍辕。
通過 Python 擴展模塊 gc 來查看不能回收的對象的詳細(xì)信息暮现。
可以通過 sys.getrefcount(obj) 來獲取對象的引用計數(shù),并根據(jù)返回值是否為 0 來判斷是否內(nèi)存泄漏楚昭。
四.函數(shù)
- 函數(shù)參數(shù)
Python 的參數(shù)傳遞有:位置參數(shù)栖袋、默認(rèn)參數(shù)、可變參數(shù)抚太、關(guān)鍵字參數(shù)
函數(shù)的傳值到底是值傳遞還是引用傳遞栋荸,要分情況:
不可變參數(shù) 用值傳遞
可變參數(shù) 引用傳遞
有這樣一段代碼,print c 會輸出什么:
a = 10
b = 20
c = [a]
a = 15
print c
>>>[10]
像列表凭舶,字典這樣的對象是通過引用傳遞晌块、和 C 語言里面的用指針傳遞數(shù)組很相似,可變對象
能在函數(shù)內(nèi)部改變帅霜。
對缺省參數(shù)的理解
缺省參數(shù)指在調(diào)用函數(shù)的時候沒有傳入?yún)?shù)的情況下匆背,調(diào)用默認(rèn)的參數(shù),在調(diào)用函數(shù)的同時賦值時身冀,所傳入的參數(shù)會替代默認(rèn)參數(shù)钝尸。
*args 是不定長參數(shù),他可以表示輸入?yún)?shù)是不確定的搂根,可以是任意多個珍促。元組方式傳入
**kwargs 是關(guān)鍵字參數(shù),賦值的時候是以鍵 = 值的方式剩愧,參數(shù)是可以任意多對在定義函數(shù)的時候不確定會有多少參數(shù)會傳入時猪叙,就可以使用兩個參數(shù)。字典式傳入
- 為什么函數(shù)名字可以當(dāng)做參數(shù)用
Python 中一切皆對象,函數(shù)名是函數(shù)在內(nèi)存中的空間穴翩,也是一個對象犬第。
4.遞歸函數(shù)終止的條件
遞歸的終止條件一般定義在遞歸函數(shù)內(nèi)部,在遞歸調(diào)用前要做一個條件判斷芒帕,根據(jù)判斷的結(jié)果選擇是繼續(xù)調(diào)用自身歉嗓,還是 return;返回終止遞歸。
終止的條件:
. 判斷遞歸的次數(shù)是否達(dá)到某一限定值
. 判斷運算的結(jié)果是否達(dá)到某個范圍等背蟆,根據(jù)設(shè)計的目的來選擇
5.回調(diào)函數(shù)鉴分,如何通信的:
回調(diào)函數(shù)是把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),將整個函數(shù)當(dāng)作一個對象带膀,賦值給調(diào)用的函數(shù)冠场。
- Python 主要的內(nèi)置數(shù)據(jù)類型都有哪些? print dir( ‘a(chǎn) ’) 的輸出
內(nèi)建類型:布爾類型本砰、數(shù)字碴裙、字符串、列表点额、元組舔株、字典、集合还棱;
輸出字符串‘a(chǎn)’的內(nèi)建方法载慈;
- 一句話解決階乘函數(shù)
reduce(lambda x,y: x*y, range(1,n+1))
8.lambda函數(shù)
lambda 函數(shù)是一個可以接收任意多個參數(shù)(包括可選參數(shù))并且返回單個表達(dá)式值的函數(shù)
.lambda 函數(shù)比較輕便,很適合需要完成一項功能,但是此功能只在此一處使用珍手,不用def給函數(shù)起名办铡。
.匿名函數(shù),一般用來給 filter琳要, map 這樣的函數(shù)式編程服務(wù);
.作為回調(diào)函數(shù)寡具,傳遞給某些應(yīng)用
這段代碼的輸出結(jié)果將是什么:
>>> def multipliers():
... return [lambda x : i * x for i in range(4)]
...
>>> print [m(2) for m in multipliers()]
[6, 6, 6, 6] (不是我們想的[0, 2稚补, 4童叠, 6])
原因:
Python 閉包的延遲綁定。這意味著內(nèi)部函數(shù)被調(diào)用時课幕,參數(shù)的值在閉包內(nèi)進(jìn)行查找厦坛。
i的變量引用,等待4次循環(huán)結(jié)束后乍惊,i指向一個值i=3,這個時候杜秸,匿名函數(shù)才開始引用i=3
解決方法:
一種解決方法就是用 Python 生成器。
def multipliers():
for i in range(4): yield lambda x : i * x
另外一個解決方案就是添加默認(rèn)參數(shù)润绎,立即綁定撬碟。
def multipliers():
return [lambda x,a=i : a* x for i in range(4)]
第二種方法:添加了一個a=i诞挨,python函數(shù)中的默認(rèn)參數(shù),是在python 解釋器遇到def(i=i)或lambda 關(guān)鍵字時小作,就必須初始化默認(rèn)參數(shù),此時for i in range(4)稼钩,每循環(huán)一次顾稀,匿名函數(shù)的默認(rèn)參數(shù)i,就需要找一次i的引用坝撑,i=0時静秆,第一個匿名函數(shù)的默認(rèn)參數(shù)值就是0,i=1時巡李,第二個匿名函數(shù)的默認(rèn)參數(shù)值就是1...
可以理解為:
def multipliers():
return [lambda x,i=0: ix, lambda x,i=1: ix, lambda x,i=2: ix, lambda x,i=3:ix i=3]
五.設(shè)計模式
1)單例模式
是一種常用的軟件設(shè)計模式抚笔,該模式的主要目的是確保某一個類只有一個實例存在。當(dāng)你希望在整個系統(tǒng)中侨拦,某個類只能出現(xiàn)一個實例時殊橙,單例對象就能派上用場。
相關(guān)鏈接
實現(xiàn)單例模式的幾種方式:
.使用模塊:
Python 的模塊就是天然的單例模式狱从,因為模塊在第一次導(dǎo)入時膨蛮,會生成 .pyc 文件,當(dāng)?shù)诙螌?dǎo)入時季研,就會直接加載 .pyc 文件敞葛,而不會再次執(zhí)行模塊代碼。因此与涡,我們只需把相關(guān)的函數(shù)和數(shù)據(jù)定義在一個模塊中惹谐,就可以獲得一個單例對象
然后再從其他模塊導(dǎo)入這個單例對象
.使用裝飾器
def Singleton(cls):
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a = 1
def __init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)
a1,a2都是同一個實例
.使用類,但是多線程時會出問題驼卖,需要加鎖
.基于new方法實現(xiàn)
當(dāng)我們實例化一個對象時氨肌,是先執(zhí)行了類的new方法(默認(rèn)調(diào)用object.new),實例化對象酌畜;然后再執(zhí)行類的init方法儒飒,對這個對象進(jìn)行初始化,
class A(object):
_instance =None
def __new__(cls,*args,**kwargs):
if cls._instance = None:
cls._instance = object.__new__(cls)
return cls._instance
else:
return cls._instance
應(yīng)用場景:
(1)資源共享的情況下檩奠,避免由于資源操作時導(dǎo)致的性能或損耗等桩了。如日志文件,應(yīng)用配置埠戳。
(2)控制資源的情況下井誉,方便資源之間的互相通信。如線程池等整胃。 1.網(wǎng)站的計數(shù)器 2.應(yīng)用配置 3.多線程池 4.數(shù)據(jù)庫配置颗圣,數(shù)據(jù)庫連接池 5.應(yīng)用程序的日志應(yīng)用....
2).工廠模式
鏈接
當(dāng)程序運行輸入一個“類型”的時候,需要創(chuàng)建于此相應(yīng)的對象。這就用到了工廠模式在岂。在如此情形中奔则,實現(xiàn)代碼基于工廠模式,可以達(dá)到可擴展蔽午,可維護(hù)的代碼易茬。當(dāng)增加一個新的類型,不在需要修改已存在的類及老,只增加能夠產(chǎn)生新類型的子類抽莱。
簡短的說,當(dāng)以下情形可以使用工廠模式:
1.不知道用戶想要創(chuàng)建什么樣的對象
2.當(dāng)你想要創(chuàng)建一個可擴展的關(guān)聯(lián)在創(chuàng)建類與支持創(chuàng)建對象的類之間骄恶。
3)裝飾器
本質(zhì)上是一個 Python 函數(shù)食铐,它可以在讓其他函數(shù)在不需要做任何代碼的變動的前提下增加額外的功能。裝飾器的返回值也是一個函數(shù)的對象.
- 生成器
生成器僧鲁、迭代器的區(qū)別:
生成器能做到迭代器能做的所有事,而使用生成器表達(dá)式取代列表解析可以同時節(jié)省內(nèi)存虐呻。使用yield變成generator
>>> X = (i for i in range(10))
>>> print type(X)
<type 'generator'>
用“一行代碼”實現(xiàn)將 1-N 的整數(shù)列表以 3 為單位分組,比如 1-100
分組后為:
print([[x for x in range(1,100)][i:i+3] for i in range(0,len(list_a),3)])
- 面向?qū)ο?br> 類和對象
- Python 中 is 和==的區(qū)別:
is 判斷的是 a 對象是否就是 b 對象寞秃,是通過 id 來判斷的铃慷。
==判斷的是 a 對象的值是否和 b 對象的值相等,是通過 value 來判斷的蜕该。
2.python 魔法方法
魔法方法就是可以給你的類增加魔力的特殊方法犁柜,如果你的對象實現(xiàn) (重載)了這些方法中的某一個,那么這個方法就會在特殊的情況下被 Python 所調(diào)用堂淡,如init馋缅,new,call绢淀,等等
3.面向?qū)ο笾性趺磳崿F(xiàn)只讀屬性
使用@property萤悴,將以訪問屬性的方式訪問方法
>>> class Person(object):
... _age =38
... @property
... def age(self):
... return self._age
...
>>> p = Person()
>>> print p.age
38
>>> p.age = 12
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>>
4.談?wù)勀銓γ嫦驅(qū)ο蟮睦斫猓?br>
面向?qū)ο笫窍鄬τ诿嫦蜻^程而言的。面向過程語言是一種基于功能分析的皆的、以算法為中心的程序設(shè)計方法覆履;而面
向?qū)ο笫且环N基于結(jié)構(gòu)分析的、以數(shù)據(jù)為中心的程序設(shè)計思想费薄。在面向?qū)ο笳Z言中有一個有很重要東西硝全,叫做類。
面向?qū)ο笥腥筇匦裕悍庋b楞抡、繼承伟众、多態(tài)。
6)正則表達(dá)式
.match 與 search 的區(qū)別:
match()函數(shù)只檢測 RE 是不是在 string 的開始位置匹配召廷,
search()會掃描整個 string 查找匹配凳厢;
.字符串查找和替換:
re.findall(r’目的字符串’账胧,’原有字符串’) #查詢
re.findall(r'cast','itcast.cn')[0]
re.sub(r‘要替換原字符’先紫,’要替換新字符’治泥,’原始字符串’)
re.sub(r'cast','heima'遮精,'itcast.cn')