隨着雲計算,大數據,人工智能等行業的興起,Python語言也變得越來越流行。在分佈式系統開發,大數據處理,人工智能,自動化部署,自動化運維等多個領域,都萌生了許多優秀的Python框架。小編認爲,Python被廣泛接受有兩方面原因:一是,Python語言的簡潔性,代碼可讀性非常強,開發效率奇高,另一方面是,Python語言功能的全面性,即可以幫你完成業務邏輯處理,又能可以完成自動化安裝部署。
總則:python一切皆對象!!!
- Python中子類怎樣調用父類方法(有2種方式,推薦使用第2種)
class A(object): #繼承object就是新式類,直接class A就是古典類 def __init__(self): print 'This is A __init__' def funA(self, s): print s class B(A): def __init__(self): super(B,self).__init__() #方法2,只有新式類可以使用 def funB1(self): A.funA(self, 'A.funA(s)') #方法1,古典類,新式類都可以使用 b = B() b.funB1()
- python中private、protected、public
private:雙下劃線開頭 protected:python無此概念,約定:以單下劃線變量作爲protected public:默認都是public
- 面向對象中的幾個概念
python無虛函數概念 python可以多繼承,無接口概念 在Python可理解爲對應於一個文件,導入就可以複用裏面的類、函數等
- 命名空間與變量作用域
常用的有: build—in name space(內建命名空間) global name space(全局命名空間) local name space(局部命名空間) 在不同的namespace中的name是沒有關係的。
- package
package是模塊的集合,每一個Package的根目錄下面都應當有一個__init__.py文件。當解釋器發現目錄下有這個文件時, 他就會認爲這是一個Package,而不是一個普通的目錄。 import a :導入模塊a from a import B:導入模塊a中的B,並將B加到局部環境空間。這種情形容易污染被導入的命名空間。
- import的加載順序
1) 當前工作目錄 2) PYTHONPATH中的目錄 3) Python安裝目錄 (/usr/local/lib/python) 事實上,模塊搜索是在保存在sys.path這個全局變量中的目錄列表中進行搜索。 導入時候執行: a)在sys.modules中查找該模塊是否已經存在,如果已經存在,則將其導入到命名空間當中,加載結束。 b)如果sys.modules中找不到對應模塊的名稱,則爲需要導入的模塊創建一個字典對象,並將該對象信息插入到sys.modules中。 c)加載前確認是否需要對模塊進行編譯,如果需要則先進行編譯 d)執行動態加載,在當前模塊的命名空間中執行編譯後的字節碼,並將其中的所有對象放入模塊對應的字典中。 也由此可見,如果命名空間有衝突(模塊名有衝突),新導入的會覆蓋系統原先導入的。
- python與C/C++相互調用
1)python調用C
python的強大之一在於可以用C/C++編寫擴展模塊.
如果我們有一些C模塊,想在python調用 裏面的函數,那麼首先需要將其用python的API寫成一個win32 DLL,然後編譯後就可以在 python中調用.
如果python提供的是python25_d.lib,因此編譯時採用release環境. 還可以用python的模塊ctypes直接在動態鏈接庫中傳遞參數到C的函數中,比如
from ctypes import *
MessageBox = windll.user32.MessageBoxA
MessageBox(0, 'Hello, world!', 'The first ctype program', 0)
2)C調用python
#include <Python.h>
int main(int argc, char *argv[])
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n" "print 'Today is',ctime(time())\n");
Py_Finalize();
return 0;
}
- python的空值
python對象的三個特徵:身份(id),類型(type),值(value),只有值可以改變,其他都只讀 id()用來標識對象的唯一身份的,type()是對象的類型 Python的特殊類型:python的空值對象只有一個值None 類型爲:NoneType
- python關鍵字is與==的區別
is判斷是否爲同一個對象,==判斷值是否相等。 is是判斷a對象是否就是b對象,是通過id判斷的, a is b相當於id(a) == id(b) ==是判斷a對象的值是否等於b對象的值
- lambda表達式
匿名函數,可以提高代碼簡潔度,但也降低了代碼的可讀性 f=lambda x,y,z:x+y+z f(1,2,3) lambda表達式求x,y,z的和,輸出6
- eval和exec
簡單來說,eval(str, [[globals [,locals]])函數將字符串str當成有效的python表達式來執行,並返回計算結果。 print eval(“1+2+3”) ===> 6 參數:globals必須是個字典,locals可以使任何一個對象 globals返回的是當前全局變量的引用,而且可以改變變量的值,即:globals返回值是可讀寫的 locals返回值是隻讀的。 與exec()的區別: exec也可以執行python代碼,但是eval卻可以計算結果並返回值。exec是語句,eval是函數。 注意:無論是eval還是exec都請慎用!!!
- with語句
with 表達式 [as 目標對象]: 可支持嵌套,主要用於文件操作,多線程鎖 with通過上下文管理器實現,用它來實現一個運行時環境,需要支持協議:__enter__(), __exit__()。 __enter__()進入上下文,返回一個對象,with將這個對象返回給目標對象。 __exit__()退出上下文,可處理異常,清理現場 with語句執行過程是這樣的: a)計算表達式的值,返回一個目標對象 b)加載__exit__()以備後用 c)調用__enter__()方法 d)給目標對象賦值(如果有) e)執行with中的代碼 f)如果e)正常退出調用__exit__() g)如過e)發生異常,調用__exit__(),如果__exit__()處理異常,返回true,則異常處理結束,如果__exit__()返回false,則將異常拋給上層。
- else語句
a)在for,while中,如果循環條件不滿足,要跳出的時候,會執行一次else,但是如果是break跳出,就不會執行else b)在try except else finally中,如果沒有發生任何異常,則執行一次else
- 幾個小經驗
finally會屏蔽異常,別用finally,爲最好。 連接字符串儘量用join不要用“+”,在字符串量大的時候,效率較低。 格式化字符串儘量用format,不要用%,核心原因是:%最終也被轉換成了format函數完成字符串格式化 Python函數傳遞的的是對象,或者說是對象的引用,不是傳值
- python變長參數的函數(args,*\kwargs)
a)*args使用列表作爲接收參數 b)\*\*kwargs使用字典作爲接收參數 但是要注意默認參數和變長參數混合使用的時候,會優先滿足普通參數,然後是默認參數,然後是變長參數。 要慎用變長參數,原因是:使用過於靈活,使代碼混亂,稍有不慎就會出現錯誤。
- 靜態方法和類方法
python中得靜態方法和類方法都依賴於裝飾器來實現。二者定義如下: class C(object): @staticmethod def f(arg1,arg2…): class C(object): @classmethod def f(cls,arg1,arg2…): 二者都可用過類名.方法名,或對象名.方法名來訪問。 a)類方法第一個參數爲本身,靜態方法無此概念,主要用於工廠方法,具體實現就交給子類實現。 b)靜態方法只能訪問靜態成員及靜態成員方法 c)靜態方法無self
- 淺拷貝與深拷貝
copy遇到類對象不進入類對象進行遞歸拷貝,二deepcopy會進入類對象進行遞歸拷貝
- 構造方法
__init__()不是構造方法,該方法僅僅做了初始化工作,真正的構造方法是 __new__(),__new__()返回對象時會自動調用__init__()。
-
property
property是用來實現屬性可管理的built-in數據類型,其實質是一種特殊的描述符,可以看做是實現了__get__(),__set__()方法的類。 使用形式: a)第一種形式: class Some_Class(object): def __init__(self): self._somevalue=0 def get_value(self): return self._somevalue def set_value(self, value): self._somevalue = value def del_attr(self): del self._somevalue x=property(get_value,set_value,del_attr,”I am x property”) obj = Some_Class() obj.x = 10 print obj.x del obj.x obj.x b)第二種形式: class Some_Class(object): _x = None def __init__(self): self._x = 0 @property def x(self): return self._x @x.setter def x(self, val): self._x = val @x.deleter def x(self): del self._x 屬性的優勢: a)代碼更簡潔,可讀性強,易於維護 b)更好的管理屬性的訪問權限
- python中的對象協議
a)用於比較的的協議__cmp__(),返回負值,0,正值,還有__eq__(),__ne__(),__lt__(),__gt__(),__add__()等等 b)容器類協議,__len__(),__getitem__(),__setitem__(),__delitem__(),__iter__() c)哈希,__hash__() d)屬性,__getattr__(),__setattr__(),__delattr__() 運算符重載:__add__(),__sub__()等等 迭代器:__iter__() 生成器:顧名思義,就是按一定的算法生成一個序列,比如:自然隊列,菲波那切數列
- 迭代器
實現:__iter__()返回一個迭代器,next()函數返回當前元素。 迭代器可以提高內存訪問速度,提高程序效率,在程序設計中,非常推薦使用。 itertools是一個庫,提供了很多高效的訪問方法,最重要的就是izip,imap等。 實際上自定義迭代器主要是實現迭代器協議__iter__()以及next()2個方法。
代碼示例:
l = [1,2,3] it = iter(l) while True: try: print it.next() except StopIteration: break; 代碼示例: class Fabs(object): def __init__(self,max): self.max = max self.n, self.a, self.b = 0, 0, 1 def __iter__(self): return self def next(self): if self.n < self.max: r = self.b self.a, self.b = self.b, self.a + self.b self.n = self.n + 1 return r raise StopIteration() print Fabs(5) for key in Fabs(5): print key
- 生成器
生成器是這樣一個函數,它記住上一次返回時在函數中的位置,對生成器的第2次(或第n次)調用跳轉至函數中間,而上次調用中函數的局部變量中的值都保持不變。
通過yield表達式實現。一般一個函數返回一個值,生成器函數可以返回多個值。
代碼示例:
def fib(n):
a,b=1,1
while a <= n:
print '-'*8
yield a
a, b = b, a+b
print '+'*8
print type(fib(1))
print type(fib(5))
print fib(5)
print '==============='
elems = fib(5)
print elems.next()
print elems.next()
print elems.next()
print elems.next()
print elems.next()
print elems.next()
- python虛擬機淺析
a)python虛擬機使用過引用計數方式進行內存管理和垃圾回收的。 b)python虛擬機會自動運行垃圾回收線程,也可以由程序員運行gc.collect()進行垃圾回收,建議類中自己定義析構函數__del__()。 c)python虛擬機有一個GIL,即全局解釋器鎖,在多線程情況下,甚至可能會導致性能低下,甚至低於單線程,尤其再IO密集型的多線程程序中更爲如此。 在python3.x版本中有些優化,但也無法去除。爲了消除或降低GIL對程序的影響,可以使用多進程multiprocessing或者C語言寫擴展的方式。
- 閉包與裝飾器
閉包是一個很神奇的東西,嵌套定義在非全局作用域裏面的函數能夠記住它在被定義的時候它所處的封閉命名空間,他的主要功能是:將一些複雜操作封裝起來。 一般用於改變一個函數的功能,如本例:調用plus返回一個新的函數,再對返回新的函數調用。裝飾器依賴於閉包實現,可以認爲是一種更簡潔的閉包 代碼示例: #!/usr/bin/python #encoding=utf-8 def f1(para): def in_fn(x): return x*para return in_fn f1 = f1(2) print f1(2) 程序輸出:4 代碼示例: #! /usr/bin/env python # coding=utf-8 # http://*** #定義一個函數 #!/usr/bin/python #encoding=utf-8 def new_fn(f): result = f(2) def in_fn(x): return x*result return in_fn @new_fn def f1(x): return x*2 print f1(2) 程序輸出:8
- 鏈表推導式
list1 = [x*2 for x in range(5)] print list1 list2 =[(i, j) for i in range(3) for j in range(i)] print list2
- and / or
python的 bool and a or b 類似於c語言中bool?a:b c = a or b 解讀: 如果a爲非0值,c值爲a,如果a爲零值,c值爲b,其實就是or的用法
- if ...else ... 的多種寫法
a=1,b=2, c=3 方式1: if a > b: c = a else: c = b 方式2: c = a if a > b else b 方式3: c = [b,a][a>b] 三個語法意義相同。
- for寫在一行
list1=[12,3,4,6,7,13,21] newList =[x for x in list1 if x > 10] #生成一個新的list print newList #輸出:[12, 13, 21] list1=[12,3,4,6,7,13,21] newList =(x for x in list1 if x > 10) #生成一個生成器 next(newList) #輸出:12 next(newList) #輸出:13next(newList) #輸出:21 next(newList) #溢出,異常
以上爲小編開發過程中總結的一些小經驗,一些甚至還是剛剛學習Python的時候作爲難點記錄下來的,通過整理,希望對大家有些幫助,同時,也歡迎大家幫忙勘誤。