一.Python 中類方法、類實(shí)例方法、靜態(tài)方法有何區(qū)別
定義區(qū)別:
1.類方法和靜態(tài)方法分別有專門的修飾符 @classmethod,@staticmethod。
2.實(shí)例方法有self參數(shù),類方法有cls參數(shù)(類參數(shù)),靜態(tài)方法是不需要這些附加參數(shù)的
3.靜態(tài)方法實(shí)際上跟該類沒有太大關(guān)系
訪問區(qū)別:
- 類和實(shí)例都可以訪問靜態(tài)方法和類方法
- 從理論上來說,類是不能訪問實(shí)例方法的,但是可以把實(shí)例/類作為參數(shù)傳入,訪問如下:
a=Myclass()
Myclass.method(a)
Myclass.method(Myclass)
二.Python 中如何動(dòng)態(tài)獲取和設(shè)置對(duì)象的屬性
hasattr,setattr,getattr
三.Python 的內(nèi)存管理機(jī)制及調(diào)優(yōu)手段
點(diǎn)這里[http://www.lxweimin.com/p/6e82c7a54c33]
內(nèi)存泄漏:有 del() 函數(shù)的對(duì)象間的循環(huán)引用是導(dǎo)致內(nèi)存泄漏的主兇。
不使用一個(gè)對(duì)象時(shí)使用:del object 來刪除一個(gè)對(duì)象的引用計(jì)數(shù)就可以有效防止內(nèi)存泄漏問題。
通過 Python 擴(kuò)展模塊 gc 來查看不能回收的對(duì)象的詳細(xì)信息。
可以通過 sys.getrefcount(obj) 來獲取對(duì)象的引用計(jì)數(shù),并根據(jù)返回值是否為 0 來判斷是否內(nèi)存泄漏。
四.函數(shù)
- 函數(shù)參數(shù)
Python 的參數(shù)傳遞有:位置參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)
函數(shù)的傳值到底是值傳遞還是引用傳遞,要分情況:
不可變參數(shù) 用值傳遞
可變參數(shù) 引用傳遞
有這樣一段代碼,print c 會(huì)輸出什么:
a = 10
b = 20
c = [a]
a = 15
print c
>>>[10]
像列表,字典這樣的對(duì)象是通過引用傳遞、和 C 語言里面的用指針傳遞數(shù)組很相似,可變對(duì)象
能在函數(shù)內(nèi)部改變。
對(duì)缺省參數(shù)的理解
缺省參數(shù)指在調(diào)用函數(shù)的時(shí)候沒有傳入?yún)?shù)的情況下,調(diào)用默認(rèn)的參數(shù),在調(diào)用函數(shù)的同時(shí)賦值時(shí),所傳入的參數(shù)會(huì)替代默認(rèn)參數(shù)。
*args 是不定長參數(shù),他可以表示輸入?yún)?shù)是不確定的,可以是任意多個(gè)。元組方式傳入
**kwargs 是關(guān)鍵字參數(shù),賦值的時(shí)候是以鍵 = 值的方式,參數(shù)是可以任意多對(duì)在定義函數(shù)的時(shí)候不確定會(huì)有多少參數(shù)會(huì)傳入時(shí),就可以使用兩個(gè)參數(shù)。字典式傳入
- 為什么函數(shù)名字可以當(dāng)做參數(shù)用
Python 中一切皆對(duì)象,函數(shù)名是函數(shù)在內(nèi)存中的空間,也是一個(gè)對(duì)象。
4.遞歸函數(shù)終止的條件
遞歸的終止條件一般定義在遞歸函數(shù)內(nèi)部,在遞歸調(diào)用前要做一個(gè)條件判斷,根據(jù)判斷的結(jié)果選擇是繼續(xù)調(diào)用自身,還是 return;返回終止遞歸。
終止的條件:
. 判斷遞歸的次數(shù)是否達(dá)到某一限定值
. 判斷運(yùn)算的結(jié)果是否達(dá)到某個(gè)范圍等,根據(jù)設(shè)計(jì)的目的來選擇
5.回調(diào)函數(shù),如何通信的:
回調(diào)函數(shù)是把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),將整個(gè)函數(shù)當(dāng)作一個(gè)對(duì)象,賦值給調(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ù)是一個(gè)可以接收任意多個(gè)參數(shù)(包括可選參數(shù))并且返回單個(gè)表達(dá)式值的函數(shù)
.lambda 函數(shù)比較輕便,很適合需要完成一項(xiàng)功能,但是此功能只在此一處使用,不用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í),參數(shù)的值在閉包內(nèi)進(jìn)行查找。
i的變量引用,等待4次循環(huán)結(jié)束后,i指向一個(gè)值i=3,這個(gè)時(shí)候,匿名函數(shù)才開始引用i=3
解決方法:
一種解決方法就是用 Python 生成器。
def multipliers():
for i in range(4): yield lambda x : i * x
另外一個(gè)解決方案就是添加默認(rèn)參數(shù),立即綁定。
def multipliers():
return [lambda x,a=i : a* x for i in range(4)]
第二種方法:添加了一個(gè)a=i,python函數(shù)中的默認(rèn)參數(shù),是在python 解釋器遇到def(i=i)或lambda 關(guān)鍵字時(shí),就必須初始化默認(rèn)參數(shù),此時(shí)for i in range(4),每循環(huán)一次,匿名函數(shù)的默認(rèn)參數(shù)i,就需要找一次i的引用,i=0時(shí),第一個(gè)匿名函數(shù)的默認(rèn)參數(shù)值就是0,i=1時(shí),第二個(gè)匿名函數(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è)計(jì)模式
1)單例模式
是一種常用的軟件設(shè)計(jì)模式,該模式的主要目的是確保某一個(gè)類只有一個(gè)實(shí)例存在。當(dāng)你希望在整個(gè)系統(tǒng)中,某個(gè)類只能出現(xiàn)一個(gè)實(shí)例時(shí),單例對(duì)象就能派上用場(chǎng)。
相關(guān)鏈接
實(shí)現(xiàn)單例模式的幾種方式:
.使用模塊:
Python 的模塊就是天然的單例模式,因?yàn)槟K在第一次導(dǎo)入時(shí),會(huì)生成 .pyc 文件,當(dāng)?shù)诙螌?dǎo)入時(shí),就會(huì)直接加載 .pyc 文件,而不會(huì)再次執(zhí)行模塊代碼。因此,我們只需把相關(guān)的函數(shù)和數(shù)據(jù)定義在一個(gè)模塊中,就可以獲得一個(gè)單例對(duì)象
然后再從其他模塊導(dǎo)入這個(gè)單例對(duì)象
.使用裝飾器
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都是同一個(gè)實(shí)例
.使用類,但是多線程時(shí)會(huì)出問題,需要加鎖
.基于new方法實(shí)現(xiàn)
當(dāng)我們實(shí)例化一個(gè)對(duì)象時(shí),是先執(zhí)行了類的new方法(默認(rèn)調(diào)用object.new),實(shí)例化對(duì)象;然后再執(zhí)行類的init方法,對(duì)這個(gè)對(duì)象進(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)用場(chǎng)景:
(1)資源共享的情況下,避免由于資源操作時(shí)導(dǎo)致的性能或損耗等。如日志文件,應(yīng)用配置。
(2)控制資源的情況下,方便資源之間的互相通信。如線程池等。 1.網(wǎng)站的計(jì)數(shù)器 2.應(yīng)用配置 3.多線程池 4.數(shù)據(jù)庫配置,數(shù)據(jù)庫連接池 5.應(yīng)用程序的日志應(yīng)用....
2).工廠模式
鏈接
當(dāng)程序運(yùn)行輸入一個(gè)“類型”的時(shí)候,需要?jiǎng)?chuàng)建于此相應(yīng)的對(duì)象。這就用到了工廠模式。在如此情形中,實(shí)現(xiàn)代碼基于工廠模式,可以達(dá)到可擴(kuò)展,可維護(hù)的代碼。當(dāng)增加一個(gè)新的類型,不在需要修改已存在的類,只增加能夠產(chǎn)生新類型的子類。
簡(jiǎn)短的說,當(dāng)以下情形可以使用工廠模式:
1.不知道用戶想要?jiǎng)?chuàng)建什么樣的對(duì)象
2.當(dāng)你想要?jiǎng)?chuàng)建一個(gè)可擴(kuò)展的關(guān)聯(lián)在創(chuàng)建類與支持創(chuàng)建對(duì)象的類之間。
3)裝飾器
本質(zhì)上是一個(gè) Python 函數(shù),它可以在讓其他函數(shù)在不需要做任何代碼的變動(dòng)的前提下增加額外的功能。裝飾器的返回值也是一個(gè)函數(shù)的對(duì)象.
- 生成器
生成器、迭代器的區(qū)別:
生成器能做到迭代器能做的所有事,而使用生成器表達(dá)式取代列表解析可以同時(shí)節(jié)省內(nèi)存。使用yield變成generator
>>> X = (i for i in range(10))
>>> print type(X)
<type 'generator'>
用“一行代碼”實(shí)現(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> 類和對(duì)象
- Python 中 is 和==的區(qū)別:
is 判斷的是 a 對(duì)象是否就是 b 對(duì)象,是通過 id 來判斷的。
==判斷的是 a 對(duì)象的值是否和 b 對(duì)象的值相等,是通過 value 來判斷的。
2.python 魔法方法
魔法方法就是可以給你的類增加魔力的特殊方法,如果你的對(duì)象實(shí)現(xiàn) (重載)了這些方法中的某一個(gè),那么這個(gè)方法就會(huì)在特殊的情況下被 Python 所調(diào)用,如init,new,call,等等
3.面向?qū)ο笾性趺磳?shí)現(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ù)勀銓?duì)面向?qū)ο蟮睦斫猓?br>
面向?qū)ο笫窍鄬?duì)于面向過程而言的。面向過程語言是一種基于功能分析的、以算法為中心的程序設(shè)計(jì)方法;而面
向?qū)ο笫且环N基于結(jié)構(gòu)分析的、以數(shù)據(jù)為中心的程序設(shè)計(jì)思想。在面向?qū)ο笳Z言中有一個(gè)有很重要東西,叫做類。
面向?qū)ο笥腥筇匦裕悍庋b、繼承、多態(tài)。
6)正則表達(dá)式
.match 與 search 的區(qū)別:
match()函數(shù)只檢測(cè) RE 是不是在 string 的開始位置匹配,
search()會(huì)掃描整個(gè) string 查找匹配;
.字符串查找和替換:
re.findall(r’目的字符串’,’原有字符串’) #查詢
re.findall(r'cast','itcast.cn')[0]
re.sub(r‘要替換原字符’,’要替換新字符’,’原始字符串’)
re.sub(r'cast','heima','itcast.cn')