本文是本人學完Python後的一遍回顧,加深理解而已,Python大神請過~html
學習Python的這幾天來,以爲Python仍是比較簡單,容易上手的,就基本語法而言,可是有些高級特性掌握起來仍是有些難度,須要時間去消化。Python給我最大的印象就是簡潔,這也正是我爲何不太喜歡Java的緣由之一。python
Python是一種用來編寫應用程序的高級程序設計語言,TIOBE程序語言排行榜2015年12月的排名以下:mysql
Python實現強勢逆襲,並且我相信,隨着時間的推移,國內Python語言將來前景也是一片向好。web
Python的特色是優雅簡單,易學易用(雖然我感受仍是有一些概念不容易理解),Python的哲學是儘可能用最少的,最簡單易懂的代碼實現須要的功能。Python適宜於開發網絡應用,腳本寫做,平常簡單小工具等等。Python的缺點是效率較低,可是在大量的場合效率卻不是那麼重要或者說Python不是其性能瓶頸,因此不要太在乎。其次是2.x-3.x的過渡使得許多3.x還缺乏不少2.x下的模塊,不過也在完善中。其次就是源代碼沒法加密,發佈Python程序其實就是發佈源代碼。正則表達式
1.若是一個字符串中有許多須要轉義的字符,而又不想寫那麼多'\',那麼能夠用 r'...' 表示 '...'內的內容不轉義。算法
2.Python可用'''...'''來表示多行內容,如:sql
>>> print('''line1 line2 line3''') line1 line2 line3
3.Python的邏輯運算and, or, not 分別對應C語言中的&&, ||, !.shell
4.Python的整數與浮點數大小都沒有範圍。數據庫
5.Python中除法有兩種: '/'除出來必是浮點數, '//'除出來是整數,即地板除。編程
6.Python中一切皆引用。每一個對象都有一個引用計數器(內部跟蹤變量)進行跟蹤,引用計數值表示該對象有多少個引用,當初次產生賦給變量時,引用計數爲1,其後沒進行下列行爲中的任意一種都會增長引用計數:
賦值: a = b 用做函數參數傳遞: func(a) 成爲容器對象的一個元素: lis = [1,2,a]
如下任意一種行爲都會減小引用計數:
del銷燬: del a 變量另賦給其餘對象:a = False 對象從容器中刪除: lis.remove(a) 身在的容器被銷燬: del lis
7.深拷貝與淺拷貝的概念與對比,有點複雜,看這篇文章
8.list,tuple和dict,set
list: 爲列表,是一個有序集合,相似於數組但又比數組功能強大,能夠隨時append,pop元素,下標從0開始,且下標爲加n模n制,即lis[-1] = lis[len-1],下標範圍[-len,len-1].
tuple:爲元組,相似於list,但list爲可變類型,而tuple不可變,即沒有append,pop等函數。一個建議是爲了安全起見,能用tuple代替list儘可能用tuple。若是tuple只有一個元素,要寫成如(1,)以免歧義。
dict:字典類型,存放key-value鍵值對,能夠根據key迅速地找出value,固然,key必須是不可變類型,以下是錯誤的:
>>> dic = {[1,2]:'value'} Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> dic = {[1,2]:'value'} TypeError: unhashable type: 'list'
list與dict的優劣對比:
dict: 1.插入,查找速度快,跟key的數目無關 2.需佔用大量內存,內存浪費嚴重 list: 1.插入,查找速度慢,O(n)的複雜度,隨元素個數增長而增長 2.佔用內存小
dict內部存放的順序和key放入的順序是沒有關係的
set:set與dict相似,至關於只有key沒有value的dict,每一個key不一樣,set間有 &, | 等操做對應集合的交,並操做。
1.函數是對象,函數名便是指向對應函數對象的引用,因此能夠將函數名賦給一個變量,至關於給函數起一個‘別名’。
>>> mmm = max >>> mmm(1,2,3) 3
2.Python函數能夠返回」多個值「,之因此打引號,是由於實際上返回的多個值拼成了一個元組,返回這個元組。
3.定義默認參數須要牢記:默認參數必須指向不變對象。不然第一次調用和第二次調用結果會不同,由於可變的默認參數調用後改變了。
4.可變參數:傳入的參數個數是可變的,能夠是0個或多個。可變參數會將你傳入的參數自動組裝爲一個tuple。在你傳入的list或tuple名字前加一個 * 即說明傳入的是可變參數。習慣寫法爲*args。
5.關鍵字參數:傳入0個或多個含參數名的參數,這些參數被自動組裝成一個dict。習慣寫法**kw,如**a表示把a中全部的鍵值對以關鍵字參數的形式傳入kw,得到一個dict,這個dict是a的一份拷貝,對kw改動不會傳遞到a
6.命名關鍵字在函數定義中跟在一個*分割符後,如
def func(a,b,*,c,d): pass
c,d爲命名關鍵字參數,能夠限制調用者能夠傳入的參數名,同時能夠提供默認值。
7.參數定義順序:必選參數,默認參數,可變參數/命名關鍵字參數,關鍵字參數。
8.切片操做格式爲lis[首下標:尾下標:間隔],若是都不填,即lis[::]則表明整個容器lis
9.用圓括號()括起來一個列表生成式建立一個生成器generator,generator保存生成算法,咱們能夠用next(g)取得生成器g的下一個返回值。生成器的好處就是咱們不須要提早生成全部列表元素,而是須要時再生成,這在某些狀況下能夠節省許多內存。算法也能夠不是列表生成式而是自定義函數,只需在函數定義中包含yield關鍵字。
10.map()和reduce(): 兩者都是高階函數。map()接收兩個參數,一個是函數,一個是Iterable序列,map將傳入的函數依次做用在序列每個元素上,並把結果做爲新的Iterator返回。reduce()相似累積計算版的map(),把一個函數做用在一個序列上,每次接收兩個參數,將結果繼續與序列的下一個元素作累積計算。
利用map和reduce編寫一個str2float函數,如把字符串'123.456'轉換成浮點數123.456:
from functools import reduce def str2float(s): def f1(x,y): return x*10 + y def char2num(s): return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] def f2(x,y): return x*0.1 + y a,b = s.split('.') print('a=',a) print('b=',b) return reduce(f1, map(char2num,a)) + 0.1*reduce(f2, map(char2num,b[::-1])) print('str2float(\'123.456\') =', str2float('123.456'))
11.fliter()函數過濾序列,相似於map()做用於每一元素,根據返回值是True或者False決定捨棄仍是保留該元素。函數返回一個Iterator。
12.sorted()函數可實現排序,相似於C++庫中的sort()函數,可是比其更加簡潔,語法爲sorted(lis,key=func,reverse=T/F)
key函數可實現自定義的排序規則,reverse表示升序仍是降序。
13.一個函數能夠返回一個函數,可是返回時該函數並未執行,因此返回函數中不要引用任何可能發生變化的變量,不然會出現邏輯錯誤。
14.裝飾器(decorator): 當須要加強函數的功能卻不但願修改函數自己,那麼能夠採用裝飾器這種運行時動態增長功能的方式,增長的功能卸載裝飾器函數中。如在執行先後打印'begin call'和'end call',能夠這樣作:
import functools def log(func): @functools.wraps(func) #爲了校訂函數簽名,最好寫上 def wrapper(*args,**kw): print('begin call') f = func(*args,**kw) print('end call') return f return wrapper @log def hah(): print('hahahaha') hah()
begin call hahahaha end call
15.偏函數: functools.partial(),做用是將一個函數的某些參數固定住,做爲新函數的參數,即固定住該參數,返回一個新函數,使調用更簡單。
1.Python實例變量能夠自由地綁定任何屬性
2.爲了避免讓內部屬性不被外部訪問,在屬性的名稱前加上兩個下劃線__,這樣就變成了一個私有變量(private),注意,不能直接訪問不表明必定不能訪問,事實上,加雙下劃線後Python就會將其更名爲‘_class名__name’,因此仍是能夠這樣來訪問這個‘私有’變量。
3.對於靜態語言,若是要求傳入一個class類型的對象,那麼傳入的對象必須是class類型或者其子類,不然將沒法調用class中的方法,而Python這樣的動態語言有‘鴨子類型’一說,即不必定要傳入class類型或其子類,而只要保證傳入的對象中有要使用的方法便可。
4.若是想要限制實例能夠綁定的屬性,那麼在定義class時定義一個__slots__變量便可,例如:
class Student(object): __slots__ = (‘name’,’age’)
注意,__slots__限制的屬性對當前類實例起徹底限制做用,且與子類共同定義其__slots__,也就是說子類能夠定義本身的__slots__,子類實例容許定義的屬性就是自身的__slots__加上父類的__slots__,即並集。
5.@ property裝飾器可使一個getter方法變成屬性,若是方法名爲me,那麼@me.setter裝飾器則可以使一個setter方法變成屬性。這樣可使代碼更簡短,同時可對參數進行必要的檢查。
6.經過多重繼承,可以使子類擁有多個父類的全部功能。
7.在類中__call__方法可以使實例對象像函數那樣直接調用,做用便是該方法定義的過程。
8.ORM(Object Relational Mapping 對象關係映射),就是把關係數據庫的一行映射爲一個對象,也就是一個類對應一個表。ORM的實現須要經過metaclass元類修改類的定義。元類能夠改變類建立時的行爲。
1.Python調試方法:
(1)直接打印
(2)斷言
(3)pdb
(4)IDE
1.序列化: 把變量從內存中變成可存儲或傳輸的過程稱之爲序列化。Python用pickle模塊實現序列化。序列化以後,就能夠把序列化後的內容存儲到磁盤上或者經過網絡進行傳輸。pickle.dumps()將對象序列化成一個bytes,而pickle.loads()能夠根據bytes反序列化出對象。
2.pickle雖好,可是它專爲Python而生,因此要在不一樣語言間傳遞對象,最好仍是xml或者json,而json表示格式是一個字符串,更易讀取,且比xml快,因此更加適宜於對象序列化。Python內置了json模塊,相應方法仍然是dumps()和loads()。
3.可是在默認狀況下,有些對象是沒法序列化的,因此咱們有時還須要定製轉換方法,告訴json該如何將某類對象轉換成可序列爲json格式的{}對象。以下便是一個轉換方法:
def mantodict(std): return { 'name': std.name, 'age': std.age, 'id': std.id }
1.Python用mutiprocessing模塊來實現多進程。
2.若是要大量建立子進程,可使用進程池:
from multiprocessing import Pool
示例以下:
.... p = Pool(4) for i in range(5): p.apply_async(long_time_task, args=(i,)) print('Waiting for all subprocesses done...') p.close() p.join() print('All subprocesses done.')
要使用進程池需新建Pool對象,對Pool對象調用join()使等待池中全部子進程運行完畢,調用join()方法以前必須調用close(),且此後沒法再新加子進程。
3.使用subprocess模塊能夠方便的啓動並管理一個子進程,控制其輸入輸出。
4.進程間通訊使用Queue,Pipes實現。
5.threading模塊管理線程。threading.lock()建立線程鎖,防止同時訪問互斥資源形成的錯誤,示例以下:
lock = threading.Lock() ... lock.acquire() ... change(mutex) ... lock.release()
6.ThreadLocal能夠解決參數在一個線程中各個函數之間互相傳遞的問題。
7.managers模塊實現分佈式進程。
1.re模塊進行正則表達式編譯和匹配,若是該表達式須要匹配不少次,那麼最好進行編譯從而大大節省時間。
正則表達式匹配郵箱例子:
import re hah = re.compile('[0-9a-zA-Z]+[\.[0-9a-zA-Z]+]*\@[0-9a-zA-Z]+\.[a-z]{2,3}') print(hah.match('someone@gmail.com').group()) print(hah.match('bill.gates@microsoft.com').group()) i = 1 while i < 10: r = input('請輸入郵箱:') print(hah.match(r).group()) i = i+1
2.datetime模塊進行日期和時間的處理,每個時間對應一個timestamp,咱們把1970年1月1日 00:00:00 UTC+00:00時區的時刻稱爲epoch time,記爲0
(1970年之前的時間timestamp爲負數),當前時間就是相對於epoch time的秒數,稱爲timestamp。字符串和datetime也能夠相互轉換,採用strptime()方法,字符串轉換爲datetime時須要設定一個識別格式,其中
%Y-%m-%d %H:%M:%S
分別表示年-月-日 時-分-秒。
從datetime得出月份,星期等字符串用strftime()方法,其中:
%a, %b %d %H:%M
分別表示星期, 月份 日期 時:分。
示例:
from datetime import datetime r = '2015-11-23 12:01' dt = datetime.strptime(r, '%Y-%m-%d %H:%M') print(dt) week = dt.strftime('%a %b %d, %H:%M') print(week) 2015-11-23 12:01:00 Mon Nov 23, 12:01
3.collections是Python內建的一個集合模塊,提供了許多有用的集合類。
4.Base64是一種任意二進制到文本字符串的編碼方法,經常使用於在URL、Cookie、網頁中傳輸少許二進制數據。
5.struct模塊用來解決bytes和其餘二進制數據類型的轉換。
6.Python的hashlib提供了常見的哈希算法,如MD5,SHA1等等。hashlib實現簡單登陸:
import hashlib db = { 'michael': 'e10adc3949ba59abbe56e057f20f883e', 'bob': '878ef96e86145580c38c87f0410ad153', 'alice': '99b1c2188db85afee403b1536010c2c9' } def get_md5(ostr): md5 = hashlib.md5() md5.update(ostr.encode()) return md5.hexdigest() def login(user, password): r = get_md5(password) for name in db: if db[name] == r: return True return False print(login('bob','abc999')) True
7.Python的內建模塊itertools
提供了很是有用的用於操做迭代對象的函數。
8.urllib提供了一系列用於操做URL的功能。如GET,POST...
9.PIL(Python Imaging Library Python圖像庫)是一個強大的圖像處理標準庫,功能強大卻又簡單易用。如今的名字叫作Pillow。能夠以下安裝Pillow:
pip3 install pillow
從下面生成數字驗證碼的程序能夠窺其一斑:
from PIL import Image, ImageDraw, ImageFont, ImageFilter import random # 隨機字母: def rndChar(): return chr(random.randint(48, 57)) # 隨機顏色1: def rndColor(): return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255)) # 隨機顏色2: def rndColor2(): return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)) # 240 x 60: width = 60 * 4 height = 60 image = Image.new('RGB', (width, height), (255, 255, 255)) # 建立Font對象: font = ImageFont.truetype('ariblk.ttf', 40) # 建立Draw對象: draw = ImageDraw.Draw(image) # 填充每一個像素: for x in range(width): for y in range(height): draw.point((x, y), fill=rndColor()) # 輸出文字: for t in range(4): draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2()) # 模糊: image = image.filter(ImageFilter.BLUR) image.save('code.jpg', 'jpeg')
效果:
1.網絡編程主要是TCP和UDP的編程,示例見【Python網絡編程】利用Python進行TCP、UDP套接字編程
2.SMTP是發送郵件的協議,Python內置對SMTP的支持,能夠發送純文本郵件、HTML郵件以及帶附件的郵件。Python對SMTP支持有smtplib
和email
兩個模塊,email
負責構造郵件,smtplib
負責發送郵件。Python內置一個poplib
模塊,實現了POP3協議,能夠直接用來收郵件。因爲如今絕大多數大型郵件服務商都採起了反垃圾郵件措施,因此這部分的簡單實驗並無成功,還需進一步研究,等遇到具體狀況再說。
3.Python內嵌了sqlite數據庫,還能夠自行安裝鏈接mysql,MySQL是當前最流行的開源數據庫,在行業內有着普遍的應用。
1.WSGI(Web Server Gateway Interface) 服務器網關接口。
2.Python web 開發框架:
-Flask:流行的Web框架
-Django:全能型Web框架
-web.py:一個小巧的Web框架
-Bottle:和Flask相似的Web框架
-Tornado:Facebook的開源異步Web框架
3.協程
1.廖雪峯Python教程【見友情連接】