基于Python2.7學(xué)習(xí)
(一)概述
一、為什么學(xué)Python
- 語法簡單腺怯,易上手月褥;
- 豐富的庫支持,對Json支持瓢喉,http宁赤、ftp、file栓票、進程等决左;
- 完整的生態(tài)圈,一切皆有可能(大數(shù)據(jù)走贪,云計算佛猛,自動化運維等常見);
結(jié)合unix-shell和C的使用習(xí)慣坠狡,在2000年發(fā)布2.0實現(xiàn)垃圾回收和Unicode支持继找。
二、特點
- 免費開源
- 動態(tài)數(shù)據(jù)類型逃沿,高層語言(沒有類型檢查)
- 可移植行婴渡,個別模塊跟操作系統(tǒng)os有關(guān)
- 面向?qū)ο?/li>
- 可擴展性,底層用C實現(xiàn)
- 豐富的標準庫
三凯亮、生態(tài)圈
- 不同解釋器支持
- web應(yīng)用開發(fā)
- 科學(xué)計算與大數(shù)據(jù)分析
- 云計算
幾種解釋器:
- Cpython解釋器:C語言實現(xiàn)边臼,常見解釋器;
- Jython解釋器:JVM假消,Java庫柠并;
- IronPython:.NET
- pypy:基于JIT的python解釋器,即時編譯富拗;
四臼予、Python web開發(fā)框架
- Django,最流行和成熟的web開發(fā)框架
- Tornado啃沪,F(xiàn)acebook開發(fā)的高性能web服務(wù)
- Uliueb粘拾,國人開發(fā)的web框架
- Flask
五、Python社區(qū)
華蟒用戶組谅阿,中文社區(qū)
啄木鳥社區(qū)
豆瓣P(guān)ython小組
六半哟、安裝Django
pip install django --index-url=http://pypi.douban.com/simple
python manage.py install
(二)Python基礎(chǔ)
一、Python參數(shù)傳遞
參數(shù)傳遞順序依次:
- 位置參數(shù)傳遞
- 關(guān)鍵字傳遞
- 表傳遞(列表)
- 字典傳遞
位置參數(shù)傳遞:值傳遞签餐;
關(guān)鍵字傳遞:根據(jù)每個參數(shù)的名字傳遞寓涨;
表傳遞:表傳遞給函數(shù)的是一個指針,指針指向序列在內(nèi)存中的位置氯檐;
字典傳遞:包裹傳參戒良;
例如:
def f(a, b=None, c=3, *args, **kwargs):
pass
混合傳參順序:先位置,再關(guān)鍵字冠摄,再包裹位置糯崎,再包裹關(guān)鍵字;
關(guān)鍵字傳參與位置傳參混用時河泳,位置傳參須在關(guān)鍵字傳參之前沃呢;
def foo(name, count=1, *args, **kwargs):
print name
print count
print args
print kwargs
foo("python", 12, *(13,14,15), **{'a':1, 'b':2})
foo("python", *(13,14,15), **{'a':1, 'b':2})
二、MVT架構(gòu)
三拆挥、Django框架
- 包管理器安裝
pip install django --index-url http://pypi.douban.com/simple
倉庫:
http://pypi.douban.com/simple # 豆瓣python模塊鏡像
http://pypi.python.org/pypi # 中央倉庫
- 從源碼安裝
下載Django的壓縮包并解壓薄霜;然后執(zhí)行:
python setup.py install
- 創(chuàng)建第一個Django的project
django-admin.py startproject [projname]
項目目錄結(jié)構(gòu):
manage.py # Django應(yīng)用的管理工具
project/
settings.py # 整個項目的核心配置文件,數(shù)據(jù)庫纸兔、緩存惰瓜、session等
urls.py # URL轉(zhuǎn)發(fā)的配置文件
wsgi.py
manage.py:管理Django項目命令行工具,支持多個命令汉矿,支持擴展自定義的命令崎坊,創(chuàng)建數(shù)據(jù)庫schema,啟動內(nèi)嵌的應(yīng)用服務(wù)器洲拇;
python manage.py [subcomand]
python manage.py help
settings.py:整個項目的核心配置文件
- 數(shù)據(jù)庫的連接信息
- 緩存配置
- session配置
- 靜態(tài)文件配置奈揍,比如:css、js
- 用戶自定義信息
運行app:
python manage.py startapp [app name]
- ORM
- Django原生支持關(guān)系映射赋续;
- 每個APP的models.py里面包含了schema的信息打月;
- 每次啟動項目的時候,都會去驗證models.py中的schema和數(shù)據(jù)庫中表對應(yīng)結(jié)構(gòu)的一致性蚕捉;
- 通過
python manage.py syncdb
來創(chuàng)建表奏篙;
model類:
每個model類表示一張表,生成的數(shù)據(jù)庫表的名字默認是APP的名字_類的名字
迫淹;
每個model類里面都有多個Filed的Instance變量秘通;
primary key:
默認情況下每個Model類,Django都會自動添加一個id的Integer Field變量作為主鍵敛熬;
用戶也可以自己指定pk字段肺稀,默認就可以;
Query:
[Model Class].Objects.get()
eg. Blog.Objects.get(pk=1)
[Model Class].Objects.[filter/exclude] # 根據(jù)特定條件篩選記錄
[Model Class].Objects.all() # 返回表中的全部數(shù)據(jù)
QuerySet:
Filter/exclude/all :三個API返回都是一個QuerySet的對象应民;
QuerySet :可以理解為Model實例的集合话原;
Lazy Mode :真正Query時查詢夕吻,不是時時查詢;
QuerySet in Chain :
Blog.Objects.all().filter(count_it=10)
ORM缺陷:
需要先手工創(chuàng)建一個空的數(shù)據(jù)庫繁仁,無法更新schema的變量涉馅;第三方解決http://south.aeracode.org/,自Django1.7+黄虱,migration被構(gòu)建到Django核心模塊中稚矿,可以使用migration工具遷移schema,更新數(shù)據(jù)庫捻浦。
- URL與視圖的映射
- 無參數(shù)的映射
url(r'^test/$', get_blog_view)
- 帶位置參數(shù)的映射
url(r'^(\d{4})/$', get_blog_view)
def get_blog_view(req, bid):
pass
- 關(guān)鍵字參數(shù)的映射
url(r'^(?P<blog id>\d{4})/$', get_blog_view)
def get_blog_view(req, blogid):
pass
URL采用最先匹配原則晤揣,匹配范圍大的URL放在最后。
- Template
{...} 變量
{% ... %} 模板標簽
{% IF %} ... {% END IF %}
{% FOR %} ... {% END FOR %}
模板上下文:
視圖函數(shù)返回一個模板的時候朱灿,需要傳入一個上下文(Context)昧识,Context是一個字典,key表示的是模板中的變量名字盗扒,value表示渲染完成后實際展示在HTML中的內(nèi)容滞诺。
def ament_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})
模板繼承:
css、HEADER环疼、FOOTER寫一次习霹,其他模塊可用
通過Block ... Extend
繼承
靜態(tài)文件處理:
JS、CSS等靜態(tài)文件的請求處理炫隶,settings.py中的STATIC
變量指定了靜態(tài)文件的根目錄淋叶。
四、Python語法
- 編寫腳本文件在第一行添加代碼
#!/usr/bin/python
#!/usr/local/bin/python
在第二行添加:
# coding:utf8
#-*- coding:utf8 -*-
- 鏈式賦值:
a, b = "django", 2
python不支持A++伪阶,A--操作煞檩;
Python3:只支持長整型;
切片操作:slice
布爾值:True 栅贴,F(xiàn)alse
dict[key] 查找斟湃,效率為O(1)
字典中key唯一,可以Hash的值檐薯。
dict[key]查找凝赛,也可以用key in dict方式來判斷字典是否包含key的鍵。
- 循環(huán)語句
for ... :
...
else:
...
當for, while正常循環(huán)退出時坛缕,會執(zhí)行else語句墓猎;當for, while非正常退出時,不會執(zhí)行else語句赚楚;
非正常退出毙沾,相當于break
try ... :
...
except _, e:
...
except e2:
...
else:
...
finally:
...
不拋異常時,執(zhí)行else語句
- Python多重繼承
Class A(ParentA, ParentB, ...):
pass
__init__
是Class構(gòu)造函數(shù)宠页,用來初始化對象
isDuplicate(s) # s是一個字符串左胞,是否含有重復(fù)的字符
isPalindrome(s) # s是一個字符串寇仓,字符串是否是回文
- 搜索路徑
Python會在以下路徑中搜索他想要的尋找的模塊:
- 程序所在文件夾
- 標準庫的安裝路徑
- 操作系統(tǒng)環(huán)境變量PYTHONPATH所包含的路徑
- Python解釋器負責(zé)內(nèi)存管理
id():返回對象的內(nèi)存地址
引用計數(shù)為0時,GC才回收內(nèi)存
整型緩沖池:整型數(shù)據(jù)被放到一個緩沖池中
a=1
b=1
id(a)與id(b)一樣烤宙,用來判斷是否為同一對象遍烦。
is:用來判斷兩個變量是不是指向同一個內(nèi)存對象
python緩存整數(shù)和短字符串,因此每個對象只存有一份门烂,所有整數(shù)的引用都指向同一個對象乳愉。即使使用賦值語句兄淫,也只是創(chuàng)造了新的引用屯远,而不是對象本身。
- 包管理器
pip是Python自帶的包管理程序
pip install web.py
pip uninstall web.py
pip install --upgrade web.py
which python # 查看Python安裝路徑
whereis python # 查看Python安裝路徑
pip install --install-option="--prefix=/home/vamei/util/" web.py # 模塊安裝路徑:/home/vamei/util/
- global
def func1():
global i
global lock
if __name__ == "__main__":
i = 100
lock = threading.Lock()
func1()
在函數(shù)中使用global聲明全局變量捕虽;i慨丐、lock為不可變數(shù)據(jù)對象,被當作一個局部變量泄私,所以用global聲明房揭;
對于可變數(shù)據(jù)對象,則不需要global聲明晌端;可以將可變數(shù)據(jù)對象作為參數(shù)來傳遞給線程函數(shù)捅暴,這些線程將共享這些可變數(shù)據(jù)對象。
- 線程
在UNIX平臺上咧纠,當某個進程終結(jié)之后蓬痒,該進程需要被其父進程調(diào)用wait,否則進程成為僵尸進程(Zombie)漆羔,所以有必要對每個process對象調(diào)用join()方法(實際上等同于wait)梧奢。對于多線程來說,由于只有一個進程演痒,所以不存在此必要性亲轨。
多線程,可以使用共享資源鸟顺,比如使用全局變量或傳遞參數(shù)惦蚊。
多進程應(yīng)避免共享資源,每個進程有自己獨立的內(nèi)存空間讯嫂,可以通過共享內(nèi)存和Manager的方法共享資源养筒。 - 列表解析
列表解析比for循環(huán)性能好很多
[expr for iter in iterable [if condition]] # 列表解析
filter(function, iter):用來對列表中的元素進行過濾,function返回false時端姚,該元素就被丟棄晕粪。
map(function, iter):把function(x)作用于列表的每一個元素,然后函數(shù)的結(jié)果根據(jù)順序構(gòu)成一個新的列表返回渐裸。
列表解析缺點:
內(nèi)存使用效率較低巫湘,每次都要把被操作的列表中的元素一次性裝載到內(nèi)存里装悲。
另一個解決方案:生成器表達式
- 每次只加載一個元素到內(nèi)存中
- 返回一個可迭代的對象
- 生成器表達式
(expr for iter in iterable [if condition]) # 返回generator對象
res = (expr for iter in iteralbe [if condition])
for i in res:
print i
對內(nèi)存要求較高時,使用生成器表達式
返回范圍較大的列表時用xrange
- 字典和集合
字典:任何一個可以被Hash的數(shù)據(jù)類型都可以用作key尚氛;字典是無序的诀诊,值可以是任意數(shù)據(jù)類型;基于Hash表實現(xiàn)阅嘶。
類實例做key属瓣,需要類實現(xiàn)__hash__
方法返回哈希值。
列表不可以做key讯柔,字典本身不能做key
元組可以做key抡蛙,但要求元組中不包含列表、字典等可變類型的數(shù)據(jù)結(jié)構(gòu)魂迄。
使用hash()函數(shù)來檢查是否可以用作key
字符串可以做key
d = {'a':1, 'b':2}
d = dict(a=1, b=2)
d.get('c', 'Default') # 若字典中沒有key為c粗截,則返回默認值Default
d.keys() # 返回已存在的key的可迭代對象
if 'a' in d:
print e.get('a') # 使用in判斷key是否在字典中
集合:元素不可重復(fù),一組無序排列的可哈希的值捣炬,支持Union熊昌、intersection等。
set:可變集合湿酸,值是可哈希的
frozenset:不可變集合
in
:判斷是否存在婿屹,for
:遍歷
集合操作函數(shù):
更新集合:add、remove推溃、update
高級操作:
- union:聯(lián)合(|)
- intersection:交集(&)
- difference:差集(-)
- symmetric_difference:異或(^)
五昂利、函數(shù)式編程
- 函數(shù)對象
def foo():
pass
foo:函數(shù)對象
foo():函數(shù)調(diào)用
a = foo
a() # 等價函數(shù)調(diào)用foo()
不支持重載,在同一模塊中定義相同名字的函數(shù)美莫,無論參數(shù)個數(shù)页眯,后定義的一個會覆蓋之前的那個。
可以返回多個值厢呵,以元組形式返回窝撵,也可以用多個變量接收返回的多個值。
- lambda
返回可調(diào)用的函數(shù)對象
不需要return來返回結(jié)果
函數(shù)聲明和定義均在一行
foo = lambda x : x+1 if x > 10 else x - 10
foo(1)
- 變量查找順序
- 局部作用域
- 全局作用域
- global關(guān)鍵字
- 閉包
def fx(x):
def gy(y):
return x + y
return gy
foo = fx(5)
print foo(10) # 結(jié)果15
裝飾器:被用于有切面需求的場景襟铭,較為經(jīng)典的有插入日志碌奉、性能測試、事務(wù)處理寒砖、Web權(quán)限校驗赐劣、Cache等。
- 無參數(shù)decorator
生成一個新的裝飾器函數(shù) - 有參decorator
有參裝飾哩都,裝飾函數(shù)先處理參數(shù)魁兼,再生成一個新的裝飾器函數(shù),然后對函數(shù)進行裝飾漠嵌。
- 面向?qū)ο缶幊?br> 特征:
- 抽象/實現(xiàn)
- 封裝/接口
- 合成
- 派生/繼承
- 多態(tài)
- 自省/反射
class A(): # 經(jīng)典類
pass
class B(object): # 新式類
pass
建議使用新式類咐汞,新式類必須有一個父類盖呼;
可使用type()測試,type(A)和type(B)
type(A):返回<type 'classobj'>
type(B):返回<type 'type'>
調(diào)用父類的__init__
方法:
A.__init__(self) # 經(jīng)典類
super(B, self).__init__()
實例方法:
方法定義在類中化撕,第一個位置參數(shù)為self几晤,self表示實例對象的本省,只能被實例所調(diào)用植阴;在調(diào)用實例方法時蟹瘾,不需顯示地傳入self,解釋器默認傳入掠手。
Python構(gòu)造函數(shù):__init__
憾朴,但不是真正的構(gòu)造函數(shù),不會創(chuàng)建對象惨撇。
使用__new__
來構(gòu)造對象
使用__init__
來初始化對象
當使用A()創(chuàng)建實例時伊脓,默認使用__init__
方法初始化對象府寒。
類變量和實例變量:
類變量綁定在類上魁衙,實例共享;實例變量綁定在實例對象上株搔,通常使用self.x來表示實例變量剖淀。給實例對象賦值時,默認創(chuàng)建實例變量纤房;在查找時纵隔,先查找對象本身的屬性實例變量,再查找類的屬性類變量炮姨。
class A(object):
author = "Guido"
def __init__(self, page):
self.page = page
book_a = A(10)
book_b = A(100)
book_a.author = "python"
print book_a.author # 輸出"python"捌刮,author作為book_a的實例變量
print book_b.author # 輸出"Guido",沒有賦值舒岸,使用類變量绅作,可用id()檢查
- 類方法和靜態(tài)方法
類方法的第一個位置參數(shù)不是self,而是cls蛾派,表示綁定到類上俄认。
使用@staticmethod
來裝飾一個靜態(tài)方法,靜態(tài)方法不需要self和cls洪乍。
使用@classmethod
來裝飾一個類函數(shù)眯杏。
類方法:
@classmethod
def class_method(cls):
pass
靜態(tài)方法:
@staticmethod
def static_method(msg):
print "[" + msg + "]"
子類若沒有自己定義__init__
方法,會默認調(diào)用基類的__init__
方法壳澳;
若子類定義了__init__
方法岂贩,則需要顯式調(diào)用基類的__init__
方法,并且傳入self參數(shù)巷波;
super()
:只工作在新式類
dir()
:查看對象所有屬性和方法
__dict__
:類的字典屬性
__doc__
:類的文檔屬性
__new__
:類函數(shù)萎津,構(gòu)造對象
__init__
:初始化對象
__del__
:當對象的引用計數(shù)為0時科平,自動調(diào)用,釋放內(nèi)存姜性,要首先調(diào)用基類的__del__
__X
:定義private變量瞪慧,只有類的內(nèi)部可以引用
對于實例對象不存在的屬性進行賦值,會動態(tài)創(chuàng)建這個屬性部念,新式類可以通過設(shè)定__slot__
的類屬性來防止這個問題弃酌。
issubclass(sub, sup) # 判斷是否為子類
isinstance(obj, classType) # 判斷是否為類的實例
super(A, self) 返回Instance
super(A, cls) 返回type
- 單元測試
- nose
- pytest
namespace:相當于字典
模塊中的變量相當于單例模式
hashcod要求唯一,計算下標
- Python單例模式
class A(object):
instance = None
def __new__(cls, *args, **kwargs):
if not cls.instance:
cls.instance = object.__new__(cls, *args, **kwargs)
return cls.instance
print id(A())
print id(A()) # 值相同
- python常用模塊
模塊文檔API:
https://docs.python.org/2/library/
使用場景:
- 操作系統(tǒng)相關(guān)
- 文件路徑處理
- 網(wǎng)絡(luò)處理
- 數(shù)據(jù)處理
os.path模塊:處理文件路徑
os.path.join("/a", "b", "c", "d.txt")
__file__ # 獲取當前文件/模塊的路徑
os模塊:
- 系統(tǒng)環(huán)境變量
- Linux系統(tǒng)上的文件處理
- 進程處理
os.environ:可以改環(huán)境變量
sys:獲取傳入給程序的外部參數(shù)argv儡炼,進程的輸入輸出流sys.stdout妓湘,sys.stdin環(huán)境信息相關(guān)。
import sys
sys.executable #判斷程序運行的環(huán)境
Python從外部獲取的參數(shù)為字符串乌询。
# 重定向stdout
_back = sys.stdout
f = open("txt.txt", "w")
sys.stdout = f
print "kkk"
f.close()
sys.platform:查看程序運行在什么平臺
subprocess:
Popen:用來創(chuàng)建子進程
網(wǎng)絡(luò)相關(guān):
- urllib
- httplib
數(shù)據(jù)處理:
- xml模塊
- json模塊
六榜贴、virtualenv和virtualenvwrapper
- virtualenv
pip install virtualenv
pip freeze
pip freeze | wc -l # 統(tǒng)計安裝的模塊
virtualenv ENV # 創(chuàng)建一個virtualenv的一個虛擬環(huán)境ENV
source ./ENV/bin/activate # 啟動ENV
deactivate # 離開virtualenv環(huán)境
which python # 查看Python可執(zhí)行文件的路徑
所有安裝在系統(tǒng)范圍內(nèi)的包對于virtualenv是可見的,這意味著若將simplejson安裝在系統(tǒng)Python目錄中妹田,它會自動提供給所有的virtualenv使用唬党。這種行為可以被更改,在創(chuàng)建virtualenv時增加--no-site-packages
選項的virtualenv就不會讀取系統(tǒng)包鬼佣,例如:virtualenv ENV --no-site-package
驶拱。
- virtualenvwrapper
建立在virtualenv上的工具,通過它可以方便的創(chuàng)建/激活/管理/銷毀虛擬環(huán)境晶衷。
workon ENV # 啟用ENV
workon # 列出所有虛擬環(huán)境
mkvirtualenv ENV # 創(chuàng)建
workon ENV
rmvirtualenv ENV
七蓝纲、回顧
- 當應(yīng)用計數(shù)為0時,GC回收變量占用的 內(nèi)存晌纫;
del 變量名
:刪除變量税迷,釋放占用的內(nèi)存;
is
語句:用來判斷兩個變量是不是指向同一個內(nèi)存對象锹漱; - 聲明編碼格式箭养,支持中文
# coding:utf8 或
# -*- coding:utf8 -*- # 一般放在第二行
#!/usr/bin/python # 放在第一行
- built-in類型
- 數(shù)值類型
- 布爾類型
- 序列類型
- 集合類型
- 映射類型
- python模塊
Python程序由多個模塊文件組成,模塊是程序執(zhí)行的唯一入口凌蔬;模塊是可以被其他模塊導(dǎo)入露懒,模塊文件為文件名。
- 模塊執(zhí)行最簡單方法
python [module].py
#! /usr/bin/python # 當前python解釋器
- 也可以使用./module.py來調(diào)用
模塊中定義了什么:
- 變量[模塊級別]
- 函數(shù)的定義
- 類的定義
- 程序的實際調(diào)用邏輯
- 數(shù)據(jù)類型
使用弱類型
- built-in類型
- 自定義的類型(類砂心,integer)
變量名字大小寫敏感懈词,以下劃線、數(shù)字辩诞、字母命名坎弯,以下劃線、字母開頭;
支持多個變量的同時定義抠忘,簡化代碼編寫:
a, b = 'django', 2
數(shù)據(jù)類型:
- 整型:32/64 bit撩炊,在python3已移除
- 長整型:沒有長度限制,受內(nèi)存大小限制
- 浮點型
- 復(fù)數(shù)類型
/ # 普通除法崎脉,兩個均為整數(shù)時拧咳,四舍五入;為浮點數(shù)時囚灼,結(jié)果為浮點數(shù)骆膝;
// # 地板除,只保留整數(shù)部分
空列表灶体、空元組阅签、空字符串、0均表示False
對象三要素:
- identity(身份)蝎抽,對應(yīng)于內(nèi)存地址政钟,不可修改
- type(類型),不可修改
- value(值)樟结,immutable不可修改和mutable可修改
list | tuple | string正負下標表示:
- 正:0,1,2,...,n-1
- 負:-n,-n-1,...,-2,-1
list支持extend操作养交,支持原地修改
[list].extend([list])
list(), tuple():創(chuàng)建了一個新的序列對象
字符串是不可變序列,任何一點修改都會創(chuàng)建新的字符串對象狭吼。每次'+'操作都會生成一個新的字符串對象层坠。
"".join(序列)
拷貝:
- 淺拷貝:list殖妇,tuple工廠函數(shù)刁笙;切片;copy模塊的copy函數(shù)谦趣;
淺拷貝不會生成一個新的 序列疲吸,指向同一個列表。 - 深拷貝:生成一個新的序列
import copy
c = copy.deepcopy(a)
Tips:持續(xù)更新前鹅。摘悴。。