中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Python基礎(chǔ)語(yǔ)法大全及知識(shí)點(diǎn)總結(jié)(珍藏版)

Python語(yǔ)言特點(diǎn):

  • 1.易于學(xué)習(xí):Python有相對(duì)較少的關(guān)鍵字,結(jié)構(gòu)簡(jiǎn)單,和一個(gè)明確定義的語(yǔ)法,學(xué)習(xí)起來(lái)更加簡(jiǎn)單。

  • 2.易于閱讀:Python代碼定義的更清晰。

  • 3.易于維護(hù):Python的成功在于它的源代碼是相當(dāng)容易維護(hù)的。

  • 4.一個(gè)廣泛的標(biāo)準(zhǔn)庫(kù):Python的最大的優(yōu)勢(shì)之一是豐富的庫(kù),跨平臺(tái)的,在UNIX,Windows和Macintosh兼容很好。

  • 5.互動(dòng)模式:互動(dòng)模式的支持,您可以從終端輸入執(zhí)行代碼并獲得結(jié)果的語(yǔ)言,互動(dòng)的測(cè)試和調(diào)試代碼片斷。

  • 6.可移植:基于其開(kāi)放源代碼的特性,Python已經(jīng)被移植(也就是使其工作)到許多平臺(tái)。

  • 7.可擴(kuò)展:如果你需要一段運(yùn)行很快的關(guān)鍵代碼,或者是想要編寫(xiě)一些不愿開(kāi)放的算法,你可以使用C或C++完成那部分程序,然后從你的Python程序中調(diào)用。

  • 8.數(shù)據(jù)庫(kù):Python提供所有主要的商業(yè)數(shù)據(jù)庫(kù)的接口。

  • 9.GUI編程:Python支持GUI可以創(chuàng)建和移植到許多系統(tǒng)調(diào)用。

  • 10.可嵌入: 你可以將Python嵌入到C/C++程序,讓你的程序的用戶獲得'腳本化'的能力。

下載地址:https://www.python.org/

懶人模式,安裝提示里勾選上自動(dòng)配置環(huán)境變量,pip等,安裝完成后,你連環(huán)境變量都不用配置了。

但是學(xué)習(xí)的人還是要謙虛一點(diǎn),配環(huán)境變量也是基本功。

“Python.exe” 所在的文件夾C:\Python\Python36-32加入的環(huán)境變量的Path下面就好了

配置完成后cmd終端里檢查一下,如下圖沒(méi)有保錯(cuò),說(shuō)明配置正確。

對(duì)縮進(jìn)要求嚴(yán)格,四個(gè)空格,不建議用Tab,不同平臺(tái)上縮進(jìn)不一樣

要輸出中文在開(kāi)頭寫(xiě)上 # -*- coding: utf-8 -*-

我使用的IDE為Pycharm,注釋為ctrl + /

官方文檔 http://docs.python.org/2/

中文文檔 http://python.usyiyi.cn/

http://www.pythondoc.com/

一張圖概況Python學(xué)習(xí)(轉(zhuǎn)自W3Cschool)

目錄:

Python基礎(chǔ)語(yǔ)法:

(1)打印出hello world

(2)注釋

(3)數(shù)據(jù)類(lèi)型

(4)運(yùn)算

(5)輸入

(6)輸出

(7)序列

(8)相等比較

(9)選擇

(10)循環(huán)

(11)字典(dict)

(12)集合(set)(不常用)

(14)pass,del,exec,eval

(15)內(nèi)建函數(shù)

Python進(jìn)階語(yǔ)法:

(1)文件

(2)錯(cuò)誤和異常

(3)模塊和包

(4)作用域

(5)高階函數(shù)

(6)裝飾器

(7)參數(shù)

(8)面向?qū)ο?/p>

(9)定制類(lèi)(魔術(shù)方法)

(10)日期和時(shí)間

(11)數(shù)學(xué)與隨機(jī)數(shù)

(12)正則表達(dá)式

Python基礎(chǔ)語(yǔ)法:

(1)打印出hello world

# -*- coding: utf-8 -*-
print 'hello world'
print '你好 世界'

(2)注釋

1、(單行注釋?zhuān)┮?# 開(kāi)頭,后面的文字直到行尾都算注釋

2、(多行注釋?zhuān)┒嘈凶⑨屖怯萌?hào)''' '''包含的(單引號(hào)和雙引號(hào)均可)

3、(中文注釋?zhuān)┮⑨屩形谋仨毘绦蜷_(kāi)頭先寫(xiě)上# -*- coding: utf-8 -*-,不然會(huì)報(bào)錯(cuò)

(3)數(shù)據(jù)類(lèi)型

1、變量不需要聲明,可以直接輸入,大小寫(xiě)敏感

2、這里的var = xxxx不叫變量賦值,而叫變量綁定,一個(gè)符號(hào)可以綁定任意類(lèi)型的值。

3、內(nèi)置函數(shù)type(), 用以查詢變量的類(lèi)型

var = 1
print var #1
print type(var) #整數(shù)類(lèi)型 # <type 'int'>
var = 1.1
print var # 1.1
print type(var) #浮點(diǎn)數(shù)類(lèi)型 # <type 'float'>
var = 'hello'
print var # hello
print type(var) #字符串 # <type 'str'>
var = (1==1)
print var # True
print type(var) #布爾型 # <type 'bool'>
var = None
print var # None
print type(var) #空值 # <type 'NoneType'>
var = 1+1j 或者complex(a,b)表示, 復(fù)數(shù)的實(shí)部a和虛部b都是浮點(diǎn)型
print var # (1+1j)
print type(var) #復(fù)數(shù)類(lèi)型 # <type 'complex'>

4、字符串以''或' '括起來(lái)的任意文本

5、布爾型(True, False,可以用and, or, not運(yùn)算,而不是C語(yǔ)言的&&和||)

6、多變量賦值

a = b = c = 1
a, b, c = 1, 2, 'john' #等號(hào)兩邊都是元組,建議加上括號(hào),增加可讀性
x,y = y,x #兩值交換,不需要temp,更加簡(jiǎn)潔

7、賦值語(yǔ)句不可以返回值,對(duì)象是通過(guò)引用傳遞的

y = (x = x + 1) #這是非法的

(4)運(yùn)算

1、加、減、乘、除、求余、乘方

2、乘方 ** 右結(jié)合

2**3=8 
2**2**3=256
(2**2)**3=64

3、整數(shù)運(yùn)算結(jié)果仍然是整數(shù),浮點(diǎn)數(shù)運(yùn)算結(jié)果仍然是浮點(diǎn)數(shù)。

但是整數(shù)和浮點(diǎn)數(shù)混合運(yùn)算的結(jié)果就變成浮點(diǎn)數(shù)了。

4、字符串與整數(shù)相乘

print 'abc' * 3 結(jié)果 abcabcabc

5、因?yàn)镻ython把0、空字符串''和None看成 False,其他數(shù)值和非空字符串都看成 True

True and 'a=T' 計(jì)算結(jié)果是 'a=T'

繼續(xù)計(jì)算 'a=T' or 'a=F' 計(jì)算結(jié)果還是 'a=T'

要解釋上述結(jié)果,又涉及到 and 和 or 運(yùn)算的一條重要法則:短路計(jì)算。

①在計(jì)算 a and b 時(shí),如果 a 是 False,則根據(jù)與運(yùn)算法則,整個(gè)結(jié)果必定為 False,因此返回 a;如果 a 是 True,則整個(gè)計(jì)算結(jié)果必定取決與 b,因此返回 b。

②在計(jì)算 a or b 時(shí),如果 a 是 True,則根據(jù)或運(yùn)算法則,整個(gè)計(jì)算結(jié)果必定為 True,因此返回 a;如果 a 是 False,則整個(gè)計(jì)算結(jié)果必定取決于 b,因此返回 b。

所以Python解釋器在做布爾運(yùn)算時(shí),只要能提前確定計(jì)算結(jié)果,它就不會(huì)往后算了,直接返回結(jié)果。

6、不支持自加(i++)和自減(i--)

7、地板除(//)除法不管操作數(shù)何種數(shù)值類(lèi)型,總是舍去小數(shù)部分,返回?cái)?shù)字序列中比真正的商小的最接近的數(shù)字。

print 5//3 #1
print 1.0//2.0 #0.0
print -1/2 #-1

(5)輸入

x = input() #1+2
print type(x) #<type 'int'>
y = raw_input() #1+2
print type(y) # <type 'str'>

1、由此可見(jiàn), input() 在對(duì)待純數(shù)字輸入返回所輸入的數(shù)字的類(lèi)型(int,float)

而raw_input() 將所有輸入作為字符串看待,返回字符串類(lèi)型。

為了避免類(lèi)型發(fā)生錯(cuò)誤,一般情況下使用 raw_input() 來(lái)與用戶交互。

(6)輸出

1、Python2 里面print可以直接接字符串或者運(yùn)算。

2、Python3 里面print變成了一個(gè)函數(shù),上面的寫(xiě)法不支持了,必須用一個(gè)括號(hào)括起來(lái),否則會(huì)報(bào)告語(yǔ)法錯(cuò)誤。

3、>>>是Python解釋器的提示符,不是代碼的一部分。

4、print語(yǔ)句也可以跟上多個(gè)字符串,用逗號(hào)“,”隔開(kāi),遇到逗號(hào)“,”會(huì)輸出一個(gè)空格:

print '1+2=',1+2 #1+2= 3

5、多行輸出使用三個(gè)引號(hào)和使用換行符\n一致

print '''哈

哈'''
print '哈\n哈\n哈'
# 輸出結(jié)果
# 哈
# 哈
# 哈
# 哈
# 哈
# 哈

6、轉(zhuǎn)義

print r'C:\log.txt'
print 'C:\\log.txt'
# C:\log.txt
# C:\log.txt

7、print 語(yǔ)句與字符串格式運(yùn)算符( % )結(jié)合使用,可實(shí)現(xiàn)字符串替換功能

print '%s is number %d!' % ('Python', 1)

%s表示由一個(gè)字符串來(lái)替換,%d表示由一個(gè)整數(shù)來(lái)替換,%f表示由一個(gè)浮點(diǎn)數(shù)來(lái)替換。

Python 非常靈活,即使將數(shù)字傳遞給 %s,也不會(huì)像其他要求嚴(yán)格的語(yǔ)言一樣引發(fā)嚴(yán)重后果。

(7)序列

1、序列有兩種: list (可變列表) 和tuple(不可變?cè)M)

2、定義:序列是一組有順序的元素的集合,可以包含一個(gè)或多個(gè)元素,也可以沒(méi)有任何元素。

list = [0,1,2,3,4,5] #列表用中括號(hào),可改變,理解為數(shù)組
tuple = (0,1,2,3,4,5) #元祖用小括號(hào),不可改變

由于Python是動(dòng)態(tài)語(yǔ)言,所以list中包含的元素并不要求都必須是同一種數(shù)據(jù)類(lèi)型

2、序列的通用操作

seq = '0123456789'
print seq[0] #序列元素的下標(biāo)從0開(kāi)始。注意不要越界
print seq[-1] #倒序索引,-1代表倒數(shù)第一。
print seq[1:5] #支持切片操作,seq[start:end],start包含在結(jié)果中,end不包含在結(jié)果中。
print range(1,101)[0:10]#從第1個(gè)數(shù)元素開(kāi)始取,到第11元素結(jié)束
print seq[7:] #seq[start:end]中的end可以省略。
print seq[-3:] #分片也支持負(fù)數(shù)。
print seq[:3] #seq[start:end]中的start也可以省略。
print seq[:] #全部省略會(huì)復(fù)制整個(gè)序列。
print seq[::2] #支持步長(zhǎng)。
print seq[::-1] #逆序輸出。
print seq[9:1:-1] #支持負(fù)步長(zhǎng)。
print range(1,101)[2::3]#從第三元素開(kāi)始取,每隔2個(gè)取一個(gè)元素,即3的倍數(shù)
print range(1,101)[4:50:5]#從第五個(gè)取,每隔4個(gè)取一個(gè),50以內(nèi)5的倍數(shù)
print [1, 2, 3] + [4, 5, 6] # 序列支持相加,這解釋了為啥字符串可以相加。
print [1, 2, 3] * 3 #序列支持相乘,這解釋了為啥字符串可以相稱(chēng)。
print [None] * 10 #生成一個(gè)空序列。
print 1 in [1, 2, 3] #成員判斷。
print range(1,101)[4::5][-10:] #切片可以嵌套,最后10個(gè)5的倍數(shù),先獲得5的倍數(shù)再取后10個(gè)

記住倒數(shù)第一個(gè)元素的索引是-1。倒序切片包含起始索引,不包含結(jié)束索引。

3、可變的列表(list)

list = [0,1,2,3,4,5]
list.append(7) #append()總是把新元素添加到list的尾部
print list # [0, 1, 2, 3, 4, 5, 7]
list.insert(0,-1) #insert()接受兩個(gè)參數(shù),第一個(gè)是索引,第二個(gè)是元素
print list # [-1, 0, 1, 2, 3, 4, 5, 7]
list.insert(-1,6) #insert(-1)是最后一個(gè)元素之前,即倒數(shù)第二個(gè)元素,因?yàn)閕nsert()前插
print list # [-1, 0, 1, 2, 3, 4, 5, 6, 7]
list.pop() #pop()方法總是刪掉最后一個(gè)元素
print list # [-1, 0, 1, 2, 3, 4, 5, 6]
list.pop(0) #參數(shù)為索引
print list # [0, 1, 2, 3, 4, 5, 6]
list[6]=7 #對(duì)list中的某一個(gè)索引賦值,就可以直接用新的元素替換掉原來(lái)的元素
print list # [0, 1, 2, 3, 4, 5, 7]
list[0],list[-1]=list[-1],list[0] #第一與最后位置調(diào)換
print list # [7, 1, 2, 3, 4, 5, 0]

在使用可變對(duì)象的方法如 sort(),extend()和 reverse()的時(shí)候要注意,這些操作會(huì)在列表

中原地執(zhí)行操作,也就是說(shuō)現(xiàn)有的列表內(nèi)容會(huì)被改變,但是沒(méi)有返回值!

4、不可變的元組(tuple)

字符串是一種特殊的元組

沒(méi)有 append()方法,也沒(méi)有insert()和pop()方法,也不能賦值

Tuple 比 list 操作速度快.如果您定義了一個(gè)值的常量集,并且唯一要用它做的是不斷地遍歷它,請(qǐng)使用 tuple 代替 list.如月份,星期。

print (1,) #一個(gè)元素的元祖。

因?yàn)?)既可以表示tuple,又可以作為括號(hào)表示運(yùn)算時(shí)的優(yōu)先級(jí),結(jié)果 (1) 被Python解釋器計(jì)算出結(jié)果 1,導(dǎo)致我們得到的不是tuple,而是整數(shù) 1。正是因?yàn)橛?)定義單元素的tuple有歧義,所以 Python 規(guī)定,單元素 tuple 要多加一個(gè)逗號(hào)“,”,這樣就避免了歧義。

可變的元組:tuple的元素指向list,而list內(nèi)的值可變

5、序列解包

x, y, z = 1, 2, 3
print x, y, z
(x, y, z) = (1, 2, 3)
print x, y, z
(x, y, z) = [1, 2, 3]
print x, y, z

(8)相等比較

#== 和 is的差別,==比較的是值,is比較的是引用。
x = [1, 2, 3]
y = x
z = [1, 2, 3]
print(x == y) #True
print(x == z) #True
print(x is y) #True
print(x is z) #False

(9)選擇

1、Python代碼的縮進(jìn)規(guī)則。具有相同縮進(jìn)的代碼被視為代碼塊

2、縮進(jìn)請(qǐng)嚴(yán)格按照Python的習(xí)慣寫(xiě)法:4個(gè)空格,不要使用Tab,更不要混合Tab和空格

3、格式

if 條件1:
statement
elif 條件2:
statement
elif 條件3:
statement
else:
statement

If后面不需要括號(hào),但是條件后面需要冒號(hào)

elif 即 else if

4、三元運(yùn)算符

x, y = 4, 3
if x < y:
 result = x
else:
 result = y
print result
#等價(jià)于
result = x if x < y else y
print result

(10)循環(huán)

1、for循環(huán)依次把list或tuple的每個(gè)元素迭代出來(lái)

格式

for 元素 in 序列:
statement

name 這個(gè)變量是在 for 循環(huán)中定義的,意思是,依次取出list中的每一個(gè)元素,并把元素賦值給 name,然后執(zhí)行for循環(huán)體(就是縮進(jìn)的代碼塊)

L = ['Adam', 'Lisa', 'Bart']
for name in L:
 print name

這樣一來(lái),遍歷一個(gè)list或tuple就非常容易了。

2、while循環(huán),不會(huì)迭代 list 或 tuple 的元素,而是根據(jù)表達(dá)式判斷循環(huán)是否結(jié)束。

while 條件:
statement

3、中斷循環(huán) break和continue

4、range()的用法

range(1,5) #代表從1到5(不包含5) [1, 2, 3, 4]
range(1,5,2) #代表從1到5,間隔2(不包含5) [1, 3]
range(5) #代表從0到5(不包含5) [0, 1, 2, 3, 4]

5、Python中,迭代永遠(yuǎn)是取出元素本身,而非元素的索引。

對(duì)于有序集合,元素確實(shí)是有索引的。使用enumerate() 函數(shù)拿到索引

L = ['Adam', 'Lisa', 'Bart', 'Paul']
for index, name in enumerate(L):
print index, '-', name
#結(jié)果
# 0 - Adam
# 1 - Lisa
# 2 - Bart
# 3 - Paul

使用 enumerate() 函數(shù),我們可以在for循環(huán)中同時(shí)綁定索引index和元素name。但是,這不是 enumerate() 的特殊語(yǔ)法。實(shí)際上,enumerate() 函數(shù)把:

['Adam', 'Lisa', 'Bart', 'Paul']

變成了類(lèi)似:

[(0, 'Adam'), (1, 'Lisa'), (2, 'Bart'), (3, 'Paul')]

因此,迭代的每一個(gè)元素實(shí)際上是一個(gè)tuple:

6、好用的zip()方法

for x, y in zip(range(1, 10), range(1, 10)):
 print(x, y)
# 結(jié)果
# (1, 1)
# (2, 2)
# (3, 3)
# (4, 4)
# (5, 5)
# (6, 6)
# (7, 7)
# (8, 8)
# (9, 9)

7、列表生成式,非常簡(jiǎn)潔

要生成[1x1, 2x2, 3x3, ..., 10x10]

print [x * x for x in range(1, 11)]
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

列表生成式的 for 循環(huán)后面還可以加上 if 判斷。例如:

print [x * x for x in range(1, 11) if x % 2 == 0]
# [4, 16, 36, 64, 100]

8、迭代器

它為類(lèi)序列對(duì)象提供了一個(gè)類(lèi)序列的接口。

迭代非序列集合(例如映射和文件)時(shí), 可以創(chuàng)建更簡(jiǎn)潔可讀的代碼。

myTuple = (123, 'xyz', 45.67)
i = iter(myTuple)
print i.next() #123
print i.next() #xyz
print i.next() #45.67
i.next() #報(bào)錯(cuò)

(11)字典(dict)

1、字典的元素沒(méi)有順序。你不能通過(guò)下標(biāo)引用元素。字典是通過(guò)鍵來(lái)引用,用大括號(hào)

查找速度快,無(wú)論dict有10個(gè)元素還是10萬(wàn)個(gè)元素,查找速度都一樣。而list的查找速度隨著元素增加而逐漸下降。

dict的缺點(diǎn)是占用內(nèi)存大,還會(huì)浪費(fèi)很多內(nèi)容

dict是按 key 查找,所以,在一個(gè)dict中,key不能重復(fù)

作為 key 的元素必須不可變

2、已知兩個(gè)列表,一個(gè)是名字,一個(gè)是成績(jī),要根據(jù)名字找到對(duì)應(yīng)的成績(jī)用兩個(gè)list不方便,如果把名字和分?jǐn)?shù)關(guān)聯(lián)起來(lái),組成類(lèi)似的查找表,即 Python中的dict

用 dict 表示“名字”-“成績(jī)”的查找表如下:

dic = {'tom':11, 'sam':57,'lily':100}
print type(dic) #<type 'dict'>
d = {
 'Adam': 95,
 'Lisa': 85,
 'Bart': 59
}
print d #{'Lisa': 85, 'Adam': 95, 'Bart': 59}

3、我們把名字稱(chēng)為key,對(duì)應(yīng)的成績(jī)稱(chēng)為value,dict就是通過(guò) key 來(lái)查找 value。

4、花括號(hào) {} 表示這是一個(gè)dict,然后按照 key: value, 寫(xiě)出來(lái)即可。最后一個(gè) key: value 的逗號(hào)可以省略。

5、由于dict也是集合,len()函數(shù)可以計(jì)算任意集合的大小:

print len(d) #運(yùn)算結(jié)果為3

一個(gè) key-value 算一個(gè),因此,dict大小為3。

6、可以簡(jiǎn)單地使用 d[key] 的形式來(lái)查找對(duì)應(yīng)的 value,這和 list 很像,不同之處是,list 必須使用索引返回對(duì)應(yīng)的元素,而dict使用key:

print d['Adam'] #95

注意: 通過(guò) key 訪問(wèn) dict 的value,只要 key 存在,dict就返回對(duì)應(yīng)的value。如果key不存在,會(huì)直接報(bào)錯(cuò):KeyError。

要避免 KeyError 發(fā)生,有兩個(gè)辦法:

一是先判斷一下 key 是否存在,用 in 操作符:

二是使用dict本身提供的一個(gè) get 方法,在Key不存在的時(shí)候,返回None:

print d.get('Bart') #59
print d.get('Paul') #None

7、在字典中增添一個(gè)新元素的方法:

d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
print d #{'Lisa': 85, 'Adam': 95, 'Bart': 59}
d['lilei'] = 99
print d #{'lilei': 99, 'Lisa': 85, 'Adam': 95, 'Bart': 59}

8、循環(huán)調(diào)用

for key in d: #或for key in d.keys()
 print d[key]
# 結(jié)果
# 99
# 85
# 95
# 59

9、字典的常用方法

print d.keys() # 返回d所有的鍵
print d.values() # 返回d所有的值
print d.items() # 返回d所有的元素(鍵值對(duì))
d.clear() # 清空d,dict變?yōu)閧}
del d['xxx’] # 刪除 d 的'xxx’元素
for key, value in d.items():
print key, ':', value

10、cmp()比較

(1)先比較字典長(zhǎng)度

(2)再比較字典的鍵

(3)最后比較字典的值

(4)都一樣就相等

(12)集合(set)(不常用)

1、dict的作用是建立一組 key 和一組 value 的映射關(guān)系,dict的key是不能重復(fù)的。

有的時(shí)候,我們只想要 dict 的 key,不關(guān)心 key 對(duì)應(yīng)的 value,目的就是保證這個(gè)集合的元素不會(huì)重復(fù),這時(shí),set就派上用場(chǎng)了。

2、set 持有一系列元素,這一點(diǎn)和 list 很像,但是set的元素沒(méi)有重復(fù),而且是無(wú)序的,這點(diǎn)和 dict 的 key很像。

3、創(chuàng)建 set 的方式是調(diào)用 set() 并傳入一個(gè) list,list的元素將作為set的元素:

s = set(['A', 'B', 'C'])
print s #set(['A', 'C', 'B'])

4、添加、刪除

s.add('D')
print s #set(['A', 'C', 'B', 'D'])
s.add('D') #已存在不會(huì)報(bào)錯(cuò)
s.remove('D')
print s #set(['A', 'C', 'B'])
s.remove('D') #報(bào)錯(cuò),需要先判斷

(13)函數(shù)

1、定義一個(gè)函數(shù)要使用 def 語(yǔ)句,依次寫(xiě)出函數(shù)名、括號(hào)、括號(hào)中的參數(shù)和冒號(hào):,然后,在縮進(jìn)塊中編寫(xiě)函數(shù)體,函數(shù)的返回值用 return 語(yǔ)句返回。

def say_b():
 print 'b'
say_b() #調(diào)用函數(shù),打印出b

2、如果沒(méi)有return語(yǔ)句,函數(shù)執(zhí)行完畢后也會(huì)返回結(jié)果,只是結(jié)果為 None。

3、函數(shù)返回多個(gè)值

import math
def move(x, y, step, angle):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
x, y = move(100, 100, 60, math.pi / 6)
print x, y #151.961524227 70.0
r = move(100, 100, 60, math.pi / 6)
print r #(151.96152422706632, 70.0)

其實(shí)這只是一種假象,Python函數(shù)返回的仍然是單一值,是一個(gè)tuple:

但是,在語(yǔ)法上,返回一個(gè)tuple可以省略括號(hào),而多個(gè)變量可以同時(shí)接收一個(gè)tuple,按位置賦給對(duì)應(yīng)的值,所以,Python的函數(shù)返回多值其實(shí)就是返回一個(gè)tuple,但寫(xiě)起來(lái)更方便。

4、在函數(shù)內(nèi)部,可以調(diào)用其他函數(shù)。如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身本身,這個(gè)函數(shù)就是遞歸函數(shù)。

def fact(n):
 if n==1:
 return 1
 return n * fact(n - 1)
print fact(10) #計(jì)算10的階乘

5、定義函數(shù)的時(shí)候,還可以有默認(rèn)參數(shù)。

def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
print power(2) #默認(rèn)計(jì)算2的平方
print power(2,3) #計(jì)算2的三次方

由于函數(shù)的參數(shù)按從左到右的順序匹配,所以默認(rèn)參數(shù)只能定義在必需參數(shù)的后面:

6、一個(gè)函數(shù)能接受任意個(gè)參數(shù),我們就可以定義一個(gè)可變參數(shù):

def fn(*args):
 print args
fn('a') #('a',)
fn('a', 'b') #('a', 'b')
fn('a', 'b', 'c') #('a', 'b', 'c')

可變參數(shù)的名字前面有個(gè) * 號(hào),我們可以傳入0個(gè)、1個(gè)或多個(gè)參數(shù)給可變參數(shù):

7、基本數(shù)據(jù)類(lèi)型的參數(shù):值傳遞

表作為參數(shù):指針傳遞

(14)pass,del,exec,eval

1、pass語(yǔ)句

pass代表該語(yǔ)句什么都不做,因?yàn)閜ython中空代碼是非法的,比如一個(gè)if語(yǔ)句要求什么內(nèi)容都不做,我們就可以使用pass語(yǔ)句。

2、del語(yǔ)句

一般來(lái)說(shuō)python會(huì)刪除那些不在使用的對(duì)象(因?yàn)槭褂谜卟粫?huì)再通過(guò)任何變量或者數(shù)據(jù)結(jié)構(gòu)引用它們)

3、exec語(yǔ)句(運(yùn)行字符串中的程序)

exec 'print 'hello world'' #hello world

4、eval函數(shù)(會(huì)計(jì)算python表達(dá)式(以字符串形式書(shū)寫(xiě)),并且返回結(jié)果)

print eval('2+ 2') #4
print eval(raw_input('please input number:')) #輸入2+2 得4

(15)內(nèi)建函數(shù)

1、cmp(obj1, obj2) 比較 obj1 和 obj2, 根據(jù)比較結(jié)果返回整數(shù) i:

if obj1 < obj2 返回i < 0
if obj1 > obj2 返回i > 0
if obj1 == obj2 返回i == 0

如果是用戶自定義對(duì)象, cmp()會(huì)調(diào)用該類(lèi)的特殊方法__cmp__()

2、str() 強(qiáng)制轉(zhuǎn)換成字符串

3、type() :詳見(jiàn)(3)數(shù)據(jù)類(lèi)型 - 3、

4、help():通過(guò)用函數(shù)名作為 help()的參數(shù)就能得到相應(yīng)的幫助信息

5、isinstance(變量名,類(lèi)型): 判斷是否是這個(gè)類(lèi)型的元素,可以用if語(yǔ)句

6、abs():取絕對(duì)值

7、enumerate():詳見(jiàn)(10)循環(huán) - 5、

8、len(seq):返回seq的長(zhǎng)度

9、sorted(iter):排序,會(huì)調(diào)用cmp()

10、zip(a1,a2……):詳見(jiàn)(10)循環(huán) - 6、

11、range():詳見(jiàn)(10)循環(huán) - 4、

12、string.lower():轉(zhuǎn)換字符串中所有大寫(xiě)字符為小寫(xiě)

13、string.upper():轉(zhuǎn)換字符串中所有小寫(xiě)字符為大寫(xiě)

14、string.strip():刪去字符串開(kāi)頭和結(jié)尾的空格

15、string.capitalize():把字符串第一個(gè)字符大寫(xiě)

16、string.title():所有單詞都以大寫(xiě)開(kāi)頭

17、max()和min():找出最大和最小值

18、sum():求和

19、reversed():倒序輸出

Python進(jìn)階語(yǔ)法:

(1)文件

1、文件也是一個(gè)對(duì)象。

2、打開(kāi)文件

f = open(文件名,模式)

文件名可以是相對(duì)路徑或者絕對(duì)路徑

模式有:'r' 只讀、“w” 寫(xiě)入、“a” 追加,“r+/w+”讀寫(xiě)

使用 'r' 或 'U' 模式打開(kāi)的文件必須是已經(jīng)存在的。 使用 'w' 模式打開(kāi)的文件若存在則首先清空, 然后(重新)創(chuàng)建。 以 'a' 模式打開(kāi)的文件是為追加數(shù)據(jù)作準(zhǔn)備的, 所有寫(xiě)入的數(shù)據(jù)都將追加到文件的末尾。 即使你 seek 到了其它的地方。 如果文件不存在, 將被自動(dòng)創(chuàng)建, 類(lèi)似以 'w'模式打開(kāi)文件。

test = open('test.txt', 'w')

3、屬性

test = open('test.txt', 'w')
print '文件名: ', test.name #文件名: test.txt
print '是否已關(guān)閉 : ', test.closed #是否已關(guān)閉 : False
print '訪問(wèn)模式 : ', test.mode #訪問(wèn)模式 : w

4、關(guān)閉 close()

test = open('test.txt', 'w')
test.close()
print '是否已關(guān)閉 : ', test.closed #是否已關(guān)閉 : True

5、寫(xiě)入write()

write()方法可將任何字符串寫(xiě)入一個(gè)打開(kāi)的文件。

write()方法不在字符串的結(jié)尾不添加換行符('\n'):

test = open('test.txt', 'w')
test.write('this is a test\n this is a test again \n')
test.close()
#可以在文件中看到
# this is a test
# this is a test again

主動(dòng)調(diào)用close()寫(xiě)緩存同步到磁盤(pán),或者寫(xiě)入數(shù)據(jù)量大于或等于寫(xiě)緩存,寫(xiě)緩存同步到磁盤(pán)

6、讀取 read()、readline()、readlines()

read(size)方法從一個(gè)打開(kāi)的文件中讀取一個(gè)字符串。size若不填則為盡量多的字符串,若填了則為結(jié)束位置。

readline()讀取當(dāng)前行,允許有參數(shù)
readlines()讀取剩余行,返回一個(gè)字符串列表
test = open ('test.txt', 'w')
test.write('python is a language \npython is a great language ')
test.close()
test = open('test.txt', 'r')
str = test.read()
print str
test.close()
#python is a language 
#python is a great language

7、文件位置

tell()方法告訴你文件內(nèi)的當(dāng)前位置;即下一次的讀寫(xiě)會(huì)發(fā)生在文件開(kāi)頭這么多字節(jié)之后:

seek(offset [,from])方法改變當(dāng)前文件的位置。Offset變量表示要移動(dòng)的字節(jié)數(shù)。From變量指定開(kāi)始移動(dòng)字節(jié)的參考位置。如果from被設(shè)為0,這意味著將文件的開(kāi)頭作為移動(dòng)字節(jié)的參考位置。如果設(shè)為1,則使用當(dāng)前的位置作為參考位置。如果它被設(shè)為2,那么該文件的末尾將作為參考位置。

test = open ('test.txt', 'w')
test.write('python is a language \npython is a great language ')
test.close()
test = open('test.txt', 'r')
str = test.read()
print 'the first input:\n',str
#輸出
# the first input:
# python is a language
# python is a great language
# 查找當(dāng)前位置
position = test.tell()
print position
#50
# 把指針再次重新定位到文件開(kāi)頭
position = test.seek(0, 0)
str2 = test.read(10)
print 'the second input:\n', str2
# the second input:
# python is
test.close()

8、重命名

Python的os模塊提供了幫你執(zhí)行文件處理操作的方法,必須先導(dǎo)入它,才可以調(diào)用。

os.rename(當(dāng)前文件名,新的文件名)

9、刪除文件

同樣需要導(dǎo)入os模塊,才可以調(diào)用。

os.remove(文件名)

(2)錯(cuò)誤和異常

1、錯(cuò)誤類(lèi)型

OverflowError數(shù)值運(yùn)算超出最大限制

ZeroDivisionError 除(或取模)零 (所有數(shù)據(jù)類(lèi)型)

AttributeError對(duì)象沒(méi)有這個(gè)屬性

IOError 輸入/輸出操作失敗

IndexError 序列中沒(méi)有此索引(index)

NameError 未聲明/初始化對(duì)象 (沒(méi)有屬性)

SyntaxError Python 語(yǔ)法錯(cuò)誤

TypeError 對(duì)類(lèi)型無(wú)效的操作

ValueError 傳入無(wú)效的參數(shù)

2、try-except處理異常

try-except語(yǔ)句用來(lái)檢測(cè)try語(yǔ)句塊中的錯(cuò)誤,從而讓except語(yǔ)句捕獲異常信息并處理。

try:
<語(yǔ)句> #運(yùn)行別的代碼
except Exception1,e:#Exception是錯(cuò)誤類(lèi)型名,e是儲(chǔ)存錯(cuò)誤,可以調(diào)用
<語(yǔ)句> #如果在try部份引發(fā)了'名字'異常
except Exception2,e:
<語(yǔ)句> #如果引發(fā)了'名字'異常,獲得附加的數(shù)據(jù)
else:
<語(yǔ)句> #如果沒(méi)有異常發(fā)生

當(dāng)try后的語(yǔ)句執(zhí)行時(shí)發(fā)生異常,python就跳回到try并執(zhí)行第一個(gè)匹配該異常的except子句,異常處理完畢,控制流就通過(guò)整個(gè)try語(yǔ)句(除非在處理異常時(shí)又引發(fā)新的異常)。如果在try子句執(zhí)行時(shí)沒(méi)有發(fā)生異常,python將執(zhí)行else語(yǔ)句后的語(yǔ)句(如果有else的話),然后控制流通過(guò)整個(gè)try語(yǔ)句。

try:
fh = open('testfile', 'w')
fh.write('This is my test file for exception handling!!')
except IOError:
print 'Error: can\'t find file or read data'
else:
print 'Written content in the file successfully' #Written content in the file successfully
try:
fh = open('testfile', 'r') #只讀文件不能寫(xiě)入
fh.write('This is my test file for exception handling!!')
except IOError,e:
print 'Error: can\'t find file or read data'
print 'catch error:',e
else:
print 'Written content in the file successfully'
#Error: can't find file or read data
#atch error: File not open for writing

except若不帶任何異常類(lèi)型,即捕獲所有發(fā)生的異常。但是不能捕獲語(yǔ)法錯(cuò)誤異常,如if a,因?yàn)槭沁\(yùn)行前錯(cuò)誤而不是運(yùn)行時(shí)錯(cuò)誤

也可帶多種類(lèi)型except(Exception1[, Exception2[,...ExceptionN]]]):

錯(cuò)誤類(lèi)型后面跟著變量e,可以print錯(cuò)誤提示

案例如下

import random
num = random.randint(0,100)
while 1:
 try:
 guess = int(raw_input('Enter 1-100:'))
 except ValueError,e:
 print 'error ! please enter 1-100'
 continue
 if guess > num:
 print 'guess bigger:',guess
 elif guess < num:
 print 'guess smaller:',guess
 else:
 print 'guess right,game over'
 break

3、try-finally語(yǔ)句

語(yǔ)句是否發(fā)生異常都將執(zhí)行最后的代碼。將異常保留下來(lái)交給系統(tǒng)處理,本身不處理異常。

作用:為處理異常事件提供清理機(jī)制,用來(lái)關(guān)閉文件或者釋放系統(tǒng)資源。

try:
<語(yǔ)句>
finally:
<語(yǔ)句> #退出try時(shí)總會(huì)執(zhí)行
raise

可以使用except語(yǔ)句或者finally語(yǔ)句,但是兩者不能同時(shí)使用。else語(yǔ)句也不能與finally語(yǔ)句同時(shí)使用。

4、try-except-finally

若try語(yǔ)句沒(méi)有捕獲異常,執(zhí)行完try代碼段后,執(zhí)行finally

若try捕獲異常,首先執(zhí)行except處理異常,然后執(zhí)行finally

5、try-except-else-finally

若try語(yǔ)句沒(méi)有捕獲異常,執(zhí)行完try代碼段后,執(zhí)行else代碼段,最后執(zhí)行finally

若try捕獲異常,首先執(zhí)行except處理錯(cuò)誤,然后執(zhí)行finally

6、try-finally-except

當(dāng)在try塊中拋出一個(gè)異常,立即執(zhí)行finally塊代碼。

finally塊中的所有語(yǔ)句執(zhí)行后,異常被再次提出,并執(zhí)行except塊代碼。

7、with語(yǔ)句

用來(lái)代替try-except-finally語(yǔ)句,使代碼更加簡(jiǎn)潔

with context[as var]:
 with_suite

context表達(dá)式返回是一個(gè)對(duì)象

var用來(lái)保存context返回對(duì)象,單個(gè)返回值或元組

with_suite使用var變量對(duì)context返回對(duì)象進(jìn)行操作

with open('1.text') as f:
for line in f.readline():
print line

1、打開(kāi)1.txt文件

2、f變量接收文件對(duì)象返回的對(duì)象

3、with中的代碼執(zhí)行完成后,關(guān)閉文件

程序使用了上下文管理器 (with...as...)。上下文管理器有隸屬于它的程序塊。當(dāng)隸屬的程序塊執(zhí)行結(jié)束的時(shí)候(也就是不再縮進(jìn)),上下文管理器自動(dòng)關(guān)閉了文件

運(yùn)用情況:①文件操作 ②進(jìn)城之間互斥操作:例如互斥鎖 ③支持上下文的其他對(duì)象

8、raise主動(dòng)拋出異常

#格式
rasie [exception[,args]]
#Exception 異常類(lèi)
#args 描述異常信息的元組
raise TypeError,'Test Error' #TypeError: Test Error

9、assert語(yǔ)句

斷言語(yǔ)句:assert語(yǔ)句是用于檢測(cè)表達(dá)式是否為真,如果為假,引發(fā)AssertionError錯(cuò)誤

#格式
assert expression [,args]
#expression 表達(dá)式
#args 判斷條件的描述信息
10、自定義異常
通過(guò)創(chuàng)建一個(gè)新的異常類(lèi),程序可以命名它們自己的異常。異常應(yīng)該是典型的繼承自Exception類(lèi),通過(guò)直接或間接的方式。
自定義異常只能主動(dòng)觸發(fā)。
class FileError(IOError):
pass
try:
raise FileError,'test error'
except FileError,e:
print e #test error
class CustomError(Exception):
def __init__(self,info):
Exception.__init__(self)
self.errorinfo = info
def __str__(self):
return 'CustomError:%s' %self.errorinfo
try:
raise CustomError('test CustomError')
except CustomError,e:
print 'ErrorInfo:',e #ErrorInfo: CustomError:test CustomError

(3)模塊和包

1、概念介紹

#test.py 自身模塊名test

import p1.util 引用p1包的模塊util

print p1.util.f(2) 調(diào)用p1.util的函數(shù)f()

如何區(qū)分包和普通目錄 包下面有個(gè)__inti__.py文件

2、如果我們只希望導(dǎo)入用到的math模塊的某幾個(gè)函數(shù),而不是所有函數(shù),可以用下面的語(yǔ)句:

from math import pow, sin, log

3、可以給函數(shù)起個(gè)“別名”來(lái)避免沖突:as

from math import log
from logging import log as logger # logging的log現(xiàn)在變成了logger
print log(10) # 調(diào)用的是math的log
logger(10, 'import from logging') # 調(diào)用的是logging的log

4、如果導(dǎo)入的模塊不存在,Python解釋器會(huì)報(bào) ImportError 錯(cuò)誤:

5、第三方模塊管理系統(tǒng)

-easy_install

-pip(推薦,已內(nèi)置到Python2.7.9)

(4)作用域

1、函數(shù)作用域LEGB L>E>G>B

L:local 函數(shù)內(nèi)部作用域

E:enclosing 函數(shù)內(nèi)部與內(nèi)嵌函數(shù)之間,即閉包

G:global全局作用域

B:bulid-in 內(nèi)置作用域 list,tuple之類(lèi)

passline = 60 #全局
def func(val):
 passline = 90 #函數(shù)內(nèi)部
 if val >= passline:
 print 'pass'
 else:
 print 'failed'
 def in_func():
 print val #函數(shù)內(nèi)部與內(nèi)嵌函數(shù)之間
 in_func()
func(69) 
#failed
#69

(5)高階函數(shù)

1、由于參數(shù) x, y和 f 都可以任意傳入,如果 f 傳入其他函數(shù),就可以得到不同的返回值。

def add(x, y, f):
return f(x) + f(y)
print add(-5, 9, abs) #abs(-5) + abs(9) = 14

2、map() 映射

map()是 Python 內(nèi)置的高階函數(shù),它接收一個(gè)函數(shù)f和一個(gè)list,并通過(guò)把函數(shù)f依次作用在 list的每個(gè)元素上,得到一個(gè)新的 list 并返回。

def f(x):
 return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) #[1, 4, 9, 16, 25, 36, 49, 64, 81]

利用map()函數(shù),可以把一個(gè) list 轉(zhuǎn)換為另一個(gè) list,只需要傳入轉(zhuǎn)換函數(shù)。

由于list包含的元素可以是任何類(lèi)型,因此,map()不僅僅可以處理只包含數(shù)值的 list,事實(shí)上它可以處理包含任意類(lèi)型的 list,只要傳入的函數(shù)f可以處理這種數(shù)據(jù)類(lèi)型。

3、reduce()折疊

reduce()函數(shù)接收的參數(shù)和 map()類(lèi)似,一個(gè)函數(shù)f,一個(gè)list,但reduce()傳入的函數(shù)f必須接收兩個(gè)參數(shù),reduce()對(duì)list的每個(gè)元素反復(fù)調(diào)用函數(shù)f,并返回最終結(jié)果值。

def f(x, y):
return x + y
print reduce(f, [1, 3, 5, 7, 9]) #25
#先計(jì)算頭兩個(gè)元素:f(1, 3),結(jié)果為4;
#再把結(jié)果和第3個(gè)元素計(jì)算:f(4, 5),結(jié)果為9;
#再把結(jié)果和第4個(gè)元素計(jì)算:f(9, 7),結(jié)果為16;
#再把結(jié)果和第5個(gè)元素計(jì)算:f(16, 9),結(jié)果為25;
#由于沒(méi)有更多的元素了,計(jì)算結(jié)束,返回結(jié)果25。
#初始值100
print reduce(f, [1, 3, 5, 7, 9], 100) #125

reduce()還可以接收第3個(gè)可選參數(shù),作為計(jì)算的初始值。

4、filter() 過(guò)濾

filter()函數(shù)接收一個(gè)函數(shù)f和一個(gè)list,這個(gè)函數(shù) f 的作用是對(duì)每個(gè)元素進(jìn)行判斷,返回 True或 False,filter()根據(jù)判斷結(jié)果自動(dòng)過(guò)濾掉不符合條件的元素,返回由符合條件元素組成的新list。

def is_odd(x): #是奇數(shù)
 return x % 2 == 1
print filter(is_odd, [1, 4, 6, 7, 9, 12, 17]) #[1, 7, 9, 17]

利用filter(),可以完成很多有用的功能,例如,刪除 None 或者空字符串:

def is_not_empty(s):
return s and len(s.strip()) > 0
print filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])
#['test', 'str', 'END']

5、sorted():對(duì)list進(jìn)行排序

print sorted([36, 5, 12, 9, 21]) #[5, 9, 12, 21, 36]

但sorted()也是一個(gè)高階函數(shù),它可以接收一個(gè)比較函數(shù)來(lái)實(shí)現(xiàn)自定義排序,比較函數(shù)的定義是,傳入兩個(gè)待比較的元素x, y,如果x應(yīng)該排在y的前面,返回-1,如果x應(yīng)該排在y的后面,返回1。如果x和y相等,返回0。

#倒序排序
def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
print sorted([36, 5, 12, 9, 21], reversed_cmp) #[36, 21, 12, 9, 5]

6、Python的函數(shù)不但可以返回int、str、list、dict等數(shù)據(jù)類(lèi)型,還可以返回函數(shù)!

def f():
 print 'call f()...'
 # 定義函數(shù)g:
 def g():
 print 'call g()...'
 # 返回函數(shù)g:
 return g
x = f() # 調(diào)用f() call f()...
x # 變量x是f()返回的函數(shù): #<function g at 0x00000000022CDA58>
x() # x指向函數(shù),因此可以調(diào)用 call g()...
x=f(),x()=g()

請(qǐng)注意區(qū)分返回函數(shù)和返回值:

def myabs():
return abs # 返回函數(shù)
def myabs2(x):
return abs(x) # 返回函數(shù)調(diào)用的結(jié)果,返回值是一個(gè)數(shù)值

在函數(shù)內(nèi)部定義的函數(shù)和外部定義的函數(shù)是一樣的,只是他們無(wú)法被外部訪問(wèn):

7、閉包(closure)

內(nèi)部函數(shù)中引用了外層函數(shù)的變量(enclosing作用域的變量),然后返回內(nèi)層函數(shù)的情況。

閉包的作用是封裝和代碼復(fù)用。

傳遞的是參數(shù)

#如果要實(shí)現(xiàn)兩個(gè)功能,可以定義兩個(gè)函數(shù)。
def func_150(val):
 passline = 90 #150
 if val >= passline:
 print ('pass')
 else:
 print 'failed'
def func_100(val):
 passline = 60 #150
 if val >= passline:
 print ('pass')
 else:
 print 'failed'
func_100(69)#pass
func_150(69)#failed
#如果用閉包的話只需要定義一個(gè)函數(shù)
def set_passline(passline):#passline
 def cmp(val):
 if val >= passline:
 print 'pass'
 else:
 print 'failed'
 return cmp #返回值是一個(gè)函數(shù)
f_100 = set_passline(60) #f_100就是cmp,f_100()就是cmp(),而且內(nèi)置一個(gè)passline=60
f_150 = set_passline(90)
f_100(69)#pass
f_150(69)#failed

傳遞的是函數(shù)

#不用閉包
def my_sum(*arg):
if len(arg)==0:
return 0
for val in arg:
if not isinstance(val,int):
return 0
return sum(arg)
def my_average(*arg):
if len(arg)==0:
return 0
for val in arg:
if not isinstance(val,int):
return 0
return sum(arg)/len(arg)
print my_sum(1,2,3,4,5) #15
print my_sum(1,2,3,4,5,'6')#0
print my_average(1,2,3,4,5)#3
print my_average()#0
#使用閉包
def my_sum(*arg):
print 'in my_sum'
return sum(arg)
def my_average(*arg):
return sum(arg)/len(arg)
def dec(func):
def in_dec(*arg):
print 'in_dec()=',arg
if len(arg) == 0:
return 0
for val in arg:
if not isinstance(val, int):
return 0
return func(*arg)
return in_dec #別加括號(hào)
#dec return in_dec -> my_sum
#my_sum = in_dec(*arg)
my_sum = dec(my_sum)
my_average = dec(my_average)#同理
print my_sum(1,2,3,4,5)
print my_sum(1,2,3,4,5,'6')
# 結(jié)果
# in_dec()= (1, 2, 3, 4, 5)
# in my_sum
# 15
# in_dec()= (1, 2, 3, 4, 5, '6')
# 0

正確使用閉包,就要確保引用的局部變量在函數(shù)返回后不能變。

返回函數(shù)不要引用任何循環(huán)變量,或者后續(xù)會(huì)發(fā)生變化的變量。

# 希望一次返回3個(gè)函數(shù),分別計(jì)算1x1,2x2,3x3:
def count():
 fs = []
 for i in range(1, 4):
 def f():
 return i*i
 fs.append(f)
 return fs
f1, f2, f3 = count()
print f1(),f2(),f3() #9 9 9
#當(dāng)count()函數(shù)返回了3個(gè)函數(shù)時(shí),這3個(gè)函數(shù)所引用的變量 i 的值已經(jīng)變成了3。由于f1、f2、f3并沒(méi)有被調(diào)用,所以,此時(shí)他們并未計(jì)算 i*i,當(dāng) f1 被調(diào)用時(shí),才計(jì)算i*i,但現(xiàn)在i的值已經(jīng)變?yōu)?
#正確如下
def count():
 fs = []
 for i in range(1, 4):
 def f(j):
 def g():
 return j*j
 return g
 r = f(i)
 fs.append(r)
 return fs
f1, f2, f3 = count()
print f1(), f2(), f3() #1 4 9

8、匿名函數(shù)lambda

def f(x):
return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) #[1, 4, 9, 16, 25, 36, 49, 64, 81]
print map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) #[1, 4, 9, 16, 25, 36, 49, 64, 81]

通過(guò)對(duì)比可以看出,匿名函數(shù) lambda x: x * x 實(shí)際上就是:

def f(x):

return x * x

關(guān)鍵字lambda表示匿名函數(shù),冒號(hào)前面的x 表示函數(shù)參數(shù)。

匿名函數(shù)有個(gè)限制,就是只能有一個(gè)表達(dá)式,不寫(xiě)return,返回值就是該表達(dá)式的結(jié)果。

使用匿名函數(shù),可以不必定義函數(shù)名,直接創(chuàng)建一個(gè)函數(shù)對(duì)象,很多時(shí)候可以簡(jiǎn)化代碼:

print sorted([1, 3, 9, 5, 0], lambda x,y: -cmp(x,y)) #[9, 5, 3, 1, 0]

返回函數(shù)的時(shí)候,也可以返回匿名函數(shù):

myabs = lambda x: -x if x < 0 else x
print myabs(-1) #1
print myabs(1) #1

(6)裝飾器

1、decorator本質(zhì)上就是一個(gè)高階函數(shù),它接收一個(gè)函數(shù)作為參數(shù),然后,返回一個(gè)新函數(shù)。

使用 decorator 用Python提供的@語(yǔ)法,這樣可以避免手動(dòng)編寫(xiě)f=decorate(f)這樣的代碼。

2、裝飾器用來(lái)裝飾函數(shù),返回一個(gè)函數(shù)對(duì)象

被裝飾函數(shù)標(biāo)識(shí)符指向返回的函數(shù)對(duì)象

def dec(func):
 print 'call dec'
 def in_dec(*arg):
 print 'in_dec()=',arg
 if len(arg) == 0:
 return 0
 for val in arg:
 if not isinstance(val, int):
 return 0
 return func(*arg)
 return in_dec #別加括號(hào)
@dec # 代替了my_sum = dec(my_sum)
def my_sum(*arg): #my_sum = in_dec
 print 'in my_sum'
 return sum(arg)
print my_sum(1,2,3,4,5)
# call dec
# in_dec()= (1, 2, 3, 4, 5)
# in my_sum
# 15

3、傳入函數(shù),含有兩個(gè)參數(shù)

def deco(func):
def in_deco(x,y):
print 'in deco'
func(x,y)
print 'call deco'
return in_deco
@deco #代替 bar = deco(bar) = in_deco #bar()-> in_deco()->bar()
def bar(x,y):
print 'in bar',x+y
bar(1,2)
# call deco
# in deco
# in bar

4、@log的定義

def log(f):
 def fn(x):
 print 'call ' + f.__name__ + '()...'
 return f(x)
 return fn
@log
def factorial(n):
 return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
# call factorial()...
# 3628800

但是,對(duì)于參數(shù)不是一個(gè)的函數(shù),調(diào)用將報(bào)錯(cuò)。@log寫(xiě)死了只含一個(gè)參數(shù)的返回函數(shù)。

5、要讓@log自適應(yīng)任何參數(shù)定義的函數(shù),可以利用Python的*args和**kw,保證任意個(gè)數(shù)的參數(shù)總是能正常調(diào)用:

可變參數(shù)*args表示任何多個(gè)無(wú)名參數(shù),它是一個(gè)tuple;**kwargs表示關(guān)鍵字參數(shù),它是一個(gè)dict。并且同時(shí)使用*args和**kwargs時(shí),必須*args參數(shù)列要在**kwargs前。

def log(f):
def fn(*args, **kw):
print 'call ' + f.__name__ + '()...'
return f(*args, **kw)
return fn
@log
def add(x, y):
return x + y
print add(1, 2)
# call add()...
# 3

6、@performance,它可以打印出函數(shù)調(diào)用的時(shí)間。

計(jì)算函數(shù)調(diào)用的時(shí)間可以記錄調(diào)用前后的當(dāng)前時(shí)間戳,然后計(jì)算兩個(gè)時(shí)間戳的差。

import time
def performance(f):
 def fn(*args, **kw):
 t1 = time.time()
 r = f(*args, **kw)
 t2 = time.time()
 print 'call %s() in %fs' % (f.__name__, (t2 - t1))
 return r
 return fn
@performance
def factorial(n):
 return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(5)
# call factorial() in 0.000000s
# 120

7、對(duì)于被裝飾的函數(shù),log打印的語(yǔ)句是不能變的(除了函數(shù)名)。

如果有的函數(shù)非常重要,希望打印出'[INFO] call xxx()...',有的函數(shù)不太重要,希望打印出'[DEBUG] call xxx()...',這時(shí),log函數(shù)本身就需要傳入'INFO'或'DEBUG'這樣的參數(shù):

@log('DEBUG')
def my_func():
pass
#把上面的定義翻譯成高階函數(shù)的調(diào)用,就是:
my_func = log('DEBUG')(my_func)
#上面的語(yǔ)句看上去還是比較繞,再展開(kāi)一下:
log_decorator = log('DEBUG')
my_func = log_decorator(my_func)
#上面的語(yǔ)句又相當(dāng)于:
log_decorator = log('DEBUG')
@log_decorator
def my_func():
pass

所以,帶參數(shù)的log函數(shù)首先返回一個(gè)decorator函數(shù),再讓這個(gè)decorator函數(shù)接收my_func并返回新函數(shù):

而且wrapper(*args, **kw)要調(diào)用外層參數(shù)prefix,所以無(wú)法拆開(kāi)

def log(prefix):
 def log_decorator(f):
 def wrapper(*args, **kw):
 print '[%s] %s()...' % (prefix, f.__name__)
 return f(*args, **kw)
 return wrapper
 return log_decorator
@log('DEBUG')
def test():
 pass
print test()
# [DEBUG] test()...
# None

8、區(qū)別

#在沒(méi)有decorator的情況下,打印函數(shù)名:
def f1(x):
pass
print f1.__name__ #f1
#有decorator的情況下,再打印函數(shù)名:
def log(f):
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper
@log
def f2(x):
pass
print f2.__name__ #wrapper

可見(jiàn),由于decorator返回的新函數(shù)函數(shù)名已經(jīng)不是'f2',而是@log內(nèi)部定義的'wrapper'。這對(duì)于那些依賴(lài)函數(shù)名的代碼就會(huì)失效。decorator還改變了函數(shù)的__doc__等其它屬性。如果要讓調(diào)用者看不出一個(gè)函數(shù)經(jīng)過(guò)了@decorator的“改造”,就需要把原函數(shù)的一些屬性復(fù)制到新函數(shù)中:

def log(f):
 def wrapper(*args, **kw):
 print 'call...'
 return f(*args, **kw)
 wrapper.__name__ = f.__name__
 wrapper.__doc__ = f.__doc__
 return wrapper

這樣寫(xiě)decorator很不方便,因?yàn)槲覀円埠茈y把原函數(shù)的所有必要屬性都一個(gè)一個(gè)復(fù)制到新函數(shù)上,所以Python內(nèi)置的functools可以用來(lái)自動(dòng)化完成這個(gè)“復(fù)制”的任務(wù):

import functools
def log(f):
@functools.wraps(f)
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper
@log
def f2(x):
pass
print f2.__name__ #f2

9、當(dāng)一個(gè)函數(shù)有很多參數(shù)時(shí),調(diào)用者就需要提供多個(gè)參數(shù)。如果減少參數(shù)個(gè)數(shù),就可以簡(jiǎn)化調(diào)用者的負(fù)擔(dān)。

比如,int()函數(shù)可以把字符串轉(zhuǎn)換為整數(shù),當(dāng)僅傳入字符串時(shí),int()函數(shù)默認(rèn)按十進(jìn)制轉(zhuǎn)換:

但int()函數(shù)也提供額外的base參數(shù),默認(rèn)為10。如果傳入base參數(shù),就可以做N進(jìn)制轉(zhuǎn)換:

print int('10') #10
print int('10', 8) #8
print int('A', 16) #10

假設(shè)要轉(zhuǎn)換大量的二進(jìn)制字符串,每次都傳入int(x, base=2)非常麻煩,于是,我們想到,可以定義一個(gè)int2()的函數(shù),默認(rèn)把base=2傳進(jìn)去:

def int2(x, base=2):
return int(x, base)
print int2('1000000') #64
print int2('1010101') #85

functools.partial就是幫助我們創(chuàng)建一個(gè)偏函數(shù)的,不需要我們自己定義int2(),可以直接使用下面的代碼創(chuàng)建一個(gè)新的函數(shù)int2:

import functools
int2 = functools.partial(int, base=2)
print int2('1000000') #64
print int2('1010101') #85

所以,functools.partial可以把一個(gè)參數(shù)多的函數(shù)變成一個(gè)參數(shù)少的新函數(shù),少的參數(shù)需要在創(chuàng)建時(shí)指定默認(rèn)值,這樣,新函數(shù)調(diào)用的難度就降低了。

(7)參數(shù)

1、位置參數(shù)必須以在被調(diào)用函數(shù)中定義的準(zhǔn)確順序來(lái)傳遞,參數(shù)數(shù)目必須一致。

2、所有必需的參數(shù)都要在默認(rèn)參數(shù)之前。

# 位置參數(shù)
def func_with_parameters(x, y):
print(x, y)
func_with_parameters(1, 2)
#默認(rèn)值參數(shù)
def func_with_default_value_parameters(x, y, z = 3):
print(x, y, z)
func_with_default_value_parameters(y = 2, x = 1)

3、如果命名了參數(shù),這里可以不按順序給出參數(shù)。

#命名參數(shù)
def func_with_named_parameters(x, y, z):
 print(x, y, z)
func_with_named_parameters(z = 1, y = 2, x = 3)

4、變長(zhǎng)的參數(shù)在函數(shù)聲明中不是顯式命名的,因?yàn)閰?shù)的數(shù)目在運(yùn)行時(shí)之前是未知的(甚至在運(yùn)行的期間,每次函數(shù)調(diào)用的參數(shù)的數(shù)目也可能是不同的),這和常規(guī)參數(shù)(位置和默認(rèn))明顯不同,常規(guī)參數(shù)都是在函數(shù)聲明中命名的。由于函數(shù)調(diào)用提供了關(guān)鍵字以及非關(guān)鍵字兩種參數(shù)類(lèi)型,python 用兩種方法來(lái)支持變長(zhǎng)參數(shù)。

func(*tuple_grp_nonkw_args, **dict_grp_kw_args)

其中的 tuple_grp_nonkw_args 是以元組形式體現(xiàn)的非關(guān)鍵字參數(shù)組, dict_grp_kw_args 是裝有關(guān)鍵字參數(shù)的字典。

5、可變長(zhǎng)的參數(shù)元組必須在位置和默認(rèn)參數(shù)之后。

# 收集多余的位置參數(shù)
def func_with_collection_rest_parameters(x, y=0, *rest):
print(x, y)
print(rest)
func_with_collection_rest_parameters(1, 2, 3, 4, 5)

星號(hào)操作符之后的形參將作為元組傳遞給函數(shù),元組保存了所有傳遞給函數(shù)的'額外'的參數(shù)(匹配了所有位置和具名參數(shù)后剩余的)。如果沒(méi)有給出額外的參數(shù),元組為空。

6、關(guān)鍵字變量參數(shù)(Dictionary)

在我們有不定數(shù)目的或者額外集合的關(guān)鍵字的情況中, 參數(shù)被放入一個(gè)字典中,字典中鍵為參數(shù)名,值為相應(yīng)的參數(shù)值。

#收集命名參數(shù)

def func_with_collection_rest_naned_parameters(*args, **kw):

print(args)

print(kw)

func_with_collection_rest_naned_parameters(1, 2, 3, x = 4, y = 5, z = 6)

func_with_collection_rest_naned_parameters([1, 2, 3], {'x': 4, 'y': 4, 'z': 6})

#這會(huì)導(dǎo)致args[0]指向第一個(gè)實(shí)參,args[1]指向第二個(gè)實(shí)參。

#([1, 2, 3], {'y': 4, 'x': 4, 'z': 6})

#{}

func_with_collection_rest_naned_parameters(*[1, 2, 3], **{'x': 4, 'y': 4, 'z': 6})

#這里的執(zhí)行相當(dāng)于
func_with_collection_rest_naned_parameters(1, 2, 3, x = 4, y = 5, z = 6)。

(8)面向?qū)ο?/p>

1、類(lèi)通過(guò)class關(guān)鍵字定義。類(lèi)名以大寫(xiě)字母開(kāi)頭,緊接著是(object),表示該類(lèi)是從哪個(gè)類(lèi)繼承下來(lái)的。

類(lèi)也要細(xì)致命名,像“AddrBookEntry”,“RepairShop”等等就是很好的名字

Python 并不支持純虛函數(shù)(像 C++)或者抽象方法(如在 JAVA 中)

class Person(object):

pass

2、有了Person類(lèi)的定義,就可以創(chuàng)建出具體的xiaoming、xiaohong等實(shí)例。創(chuàng)建實(shí)例使用類(lèi)名+(),類(lèi)似函數(shù)調(diào)用的形式創(chuàng)建:

Python 規(guī)范推薦使用駱駝?dòng)浄ǖ南聞澗€方式,比如,“update_phone”“update_email”。

xiaoming = Person()

xiaohong = Person()

3、由于Python是動(dòng)態(tài)語(yǔ)言,對(duì)每一個(gè)實(shí)例,都可以直接給他們的屬性賦值:

xiaoming = Person()

xiaoming.name = 'Xiao Ming'

xiaoming.gender = 'Male'

xiaoming.birth = '1990-1-1'

4、構(gòu)造函數(shù)__init__()方法

class Person(object):

def __init__(self, name, gender, birth):

self.name = name

self.gender = gender

self.birth = birth

__init__()方法的第一個(gè)參數(shù)必須是self(也可以用別的名字,但建議使用習(xí)慣用法),后續(xù)參數(shù)則可以自由指定,和定義函數(shù)沒(méi)有任何區(qū)別。

相應(yīng)地,創(chuàng)建實(shí)例時(shí),就必須要提供除self以外的參數(shù):

xiaoming = Person('Xiao Ming', 'Male', '1991-1-1')

xiaohong = Person('Xiao Hong', 'Female', '1992-2-2')

print xiaoming.name # 輸出 'Xiao Ming'

print xiaohong.birth # 輸出 '1992-2-2'

定義Person類(lèi)的__init__方法,除了接受 name、gender 和 birth 外,還可接受任意關(guān)鍵字參數(shù),并把他們都作為屬性賦值給實(shí)例。

要定義關(guān)鍵字參數(shù),使用 **kw;

除了可以直接使用self.name = 'xxx'設(shè)置一個(gè)屬性外,還可以通過(guò) setattr(self, 'name', 'xxx') 設(shè)置屬性。

class Person(object):
 def __init__(self, name, gender, birth, **kw):
 self.name = name
 self.gender = gender
 self.birth = birth
 for k, v in kw.iteritems():
 setattr(self, k, v)
xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student')
print xiaoming.name #輸出Xiao Ming
print xiaoming.job #輸出Student

5、析構(gòu)函數(shù)

由于 Python 具有垃圾對(duì)象回收機(jī)制(靠引用計(jì)數(shù)),這個(gè)函數(shù)要直到該實(shí)例對(duì)象所有的引用都被清除掉后才會(huì)執(zhí)行。所以很少用到。

class Person(object):

def __init__(self, ……):

6、Python對(duì)屬性權(quán)限的控制是通過(guò)屬性名來(lái)實(shí)現(xiàn)的,如果一個(gè)屬性由雙下劃線開(kāi)頭(__),該屬性就無(wú)法被外部訪問(wèn)。

class Person(object):
def __init__(self, name):
self.name = name
self._title = 'Mr'
self.__job = 'Student'
p = Person('Bob')
print p.name # => Bob
print p._title # => Mr
print p._Person__job # => Student #所以實(shí)際上并不是嚴(yán)格的私有成員
print p.__job # => Error

但是,如果一個(gè)屬性以'__xxx__'的形式定義,那它又可以被外部訪問(wèn)了,以'__xxx__'定義的屬性在Python的類(lèi)中被稱(chēng)為特殊屬性,有很多預(yù)定義的特殊屬性可以使用,通常我們不要把普通屬性用'__xxx__'定義。

以單下劃線開(kāi)頭的屬性'_xxx'可以在子類(lèi)中使用,不應(yīng)該被外部訪問(wèn),理解為保護(hù)成員。

'__xxx'可以理解為私有成員,但實(shí)質(zhì)并不是,不建議訪問(wèn)。

7、類(lèi)屬性是直接綁定在類(lèi)上的,所以,訪問(wèn)類(lèi)屬性不需要?jiǎng)?chuàng)建實(shí)例,就可以直接訪問(wèn):

class Person(object):
 address = 'Earth'
 def __init__(self, name):
 self.name = name
p1=Person(xiaoming)
print Person.address # => Earth
print p1.address # => Earth
# 由于Python是動(dòng)態(tài)語(yǔ)言,類(lèi)屬性也是可以動(dòng)態(tài)添加和修改的:
Person.address = 'China'
print p1.address # => 'China'

8、在實(shí)例變量上修改類(lèi)屬性

當(dāng)實(shí)例屬性和類(lèi)屬性重名時(shí),實(shí)例屬性優(yōu)先級(jí)高,它將屏蔽掉對(duì)類(lèi)屬性的訪問(wèn)。而其他不變

9、訪問(wèn)類(lèi)的屬性

有兩種方法。最簡(jiǎn)單的是使用 dir()內(nèi)建函數(shù)。另外是通過(guò)訪問(wèn)類(lèi)的字典屬性__dict__,這是所有類(lèi)都具備的特殊屬性之一。

10、實(shí)例的方法。

實(shí)例的方法就是在類(lèi)中定義的函數(shù),它的第一個(gè)參數(shù)永遠(yuǎn)是self,指向調(diào)用該方法的實(shí)例本身,其他參數(shù)和一個(gè)普通函數(shù)是完全一樣的:在其他語(yǔ)言中,self就是this.

class Person(object):
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
p1 = Person('Bob')
print p1.get_name() # self不需要顯式傳入 # => Bob
print p1.__dict__ # {'_Person__name': 'Bob'}
print p1._Person__name # => Bob

在實(shí)例方法內(nèi)部,可以訪問(wèn)所有實(shí)例屬性,這樣,如果外部需要訪問(wèn)私有屬性,可以通過(guò)方法調(diào)用獲得,這種數(shù)據(jù)封裝的形式除了能保護(hù)內(nèi)部數(shù)據(jù)一致性外,還可以簡(jiǎn)化外部調(diào)用的難度。

11、方法也分實(shí)例方法和類(lèi)方法。

@classmethod 調(diào)用的時(shí)候用類(lèi)名而不是某個(gè)對(duì)象

在class中定義的全部是實(shí)例方法,實(shí)例方法第一個(gè)參數(shù)self是實(shí)例本身。

要在class中定義類(lèi)方法,需要這么寫(xiě):

class Person(object):
 count = 0
 @classmethod
 def how_many(cls):
 return cls.count
 
 def __init__(self, name):
 self.name = name
 Person.count = Person.count + 1
print Person.how_many() #0
p1 = Person('Bob')
print Person.how_many() #1

通過(guò)標(biāo)記一個(gè)@classmethod,該方法將綁定到Person類(lèi)上,而非類(lèi)的實(shí)例。類(lèi)方法的第一個(gè)參數(shù)將傳入類(lèi)本身,通常將參數(shù)名命名為cls,上面的cls.count實(shí)際上相當(dāng)于Person.count。

因?yàn)槭窃陬?lèi)上調(diào)用,而非實(shí)例上調(diào)用,因此類(lèi)方法無(wú)法獲得任何實(shí)例變量,只能獲得類(lèi)的引用

12、@property 像訪問(wèn)屬性一樣調(diào)用方法,即不用括號(hào)

class Person(object):
count = 0
def __init__(self, name,age,weight):
self.name = name
self._age = age
self.__weight = weight
Person.count = Person.count + 1
@classmethod
def how_many(cls):
return cls.count
@property
def get_weight(self):
return self.__weight
print Person.how_many() # 0
p1 = Person('Bob',20,50)
print Person.how_many() # 1
print p1.get_weight #50

get/set方法:

class Student(object):
 def __init__(self, name, score):
 self.name = name
 self.__score = score
 def get_score(self):
 return self.__score
 def set_score(self, score):
 if score < 0 or score > 100:
 raise ValueError('invalid score')
 self.__score = score
#但是寫(xiě) s.get_score() 和 s.set_score() 沒(méi)有直接寫(xiě) s.score 來(lái)得直接。

用裝飾器函數(shù)把get/set方法“裝飾”成屬性調(diào)用:

把一個(gè)getter方法變成屬性,只需要加上 @ property就可以了

setter是關(guān)鍵字,這種“@+方法名字+點(diǎn)+setter”是個(gè)固定格式與@property搭配使用。

class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, score):
if score < 0 or score > 100:
raise ValueError('invalid score')
self.__score = score
s = Student('Bob',100)
print s.score #100
s.score = 90 #屬性賦值
print s.score #90

13、函數(shù)和方法

函數(shù)是直接調(diào)用函數(shù)名,僅僅是一部分代碼

方法必須和對(duì)象結(jié)合在一起使用,是類(lèi)的一部分

方法可以看做是類(lèi)的屬性

class Test(object):
 def test(self):
 pass
a = Test()
print a.test #<bound method Test.test of <__main__.Test object at 0x00000000022B8E10>>
print a.test() #None
a.test= '123'
print a.test #123
print a.test() #報(bào)錯(cuò)

14、定義子類(lèi)

class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender) #初始化
self.score = score

一定要用super(Student, self).__init__(name, gender)去初始化父類(lèi),否則,繼承自Person的Student將沒(méi)有name和gender。

函數(shù)super(Student, self)將返回當(dāng)前類(lèi)繼承的父類(lèi),即Person,然后調(diào)用__init__()方法,注意self參數(shù)已在super()中傳入,在__init__()中將隱式傳遞,不需要寫(xiě)出(也不能寫(xiě))

使用super()的漂亮之處在于,你不需要明確給出任何基類(lèi)名字,這意味著如果你改變了類(lèi)繼承關(guān)系,你只需要改一行代碼(class語(yǔ)句本身)而不必在大量代碼中去查找所有被修改的那個(gè)類(lèi)的名字。

一個(gè)實(shí)例可以看成它本身的類(lèi)型,也可以看成它父類(lèi)的類(lèi)型。

15、多重繼承

class A(object):
 def __init__(self, a):
 print 'init A...'
 self.a = a
class B(A):
 def __init__(self, a):
 super(B, self).__init__(a)
 print 'init B...'
class C(A):
 def __init__(self, a):
 super(C, self).__init__(a)
 print 'init C...'
class D(B, C):
 def __init__(self, a):
 super(D, self).__init__(a)
 print 'init D...'

像這樣,D 同時(shí)繼承自 B 和 C,也就是 D 擁有了 A、B、C 的全部功能。多重繼承通過(guò)super()調(diào)用__init__()方法時(shí),A 雖然被繼承了兩次,但__init__()只調(diào)用一次:

多重繼承的目的是從兩種繼承樹(shù)中分別選擇并繼承出子類(lèi),以便組合功能使用。

舉個(gè)例子,Python的網(wǎng)絡(luò)服務(wù)器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,而服務(wù)器運(yùn)行模式有多進(jìn)程ForkingMixin和多線程ThreadingMixin兩種。

要?jiǎng)?chuàng)建多進(jìn)程模式的 TCPServer:

class MyTCPServer(TCPServer, ForkingMixin)

pass

要?jiǎng)?chuàng)建多線程模式的 UDPServer:

class MyUDPServer(UDPServer, ThreadingMixin):

pass

如果沒(méi)有多重繼承,要實(shí)現(xiàn)上述所有可能的組合需要 4x2=8 個(gè)子類(lèi)。

16、多態(tài)

用一個(gè)類(lèi)繼承多個(gè)類(lèi),調(diào)用同一個(gè)方法,會(huì)有不同的反應(yīng),因?yàn)楸恢貙?xiě)了。

17、鴨子類(lèi)型

定義:“當(dāng)看到一只鳥(niǎo)走起來(lái)像鴨子、游泳起來(lái)像鴨子、叫起來(lái)也像鴨子,那么這只鳥(niǎo)就可以被稱(chēng)為鴨子。

這種風(fēng)格適用于動(dòng)態(tài)語(yǔ)言(比如PHP、Python、Ruby、Typescript、Perl、Objective-C、Lua、Julia、JavaScript、Java、Groovy、C#等)和某些靜態(tài)語(yǔ)言

在鴨子類(lèi)型中,關(guān)注的不是對(duì)象的類(lèi)型本身,而是它是如何使用的。例如,在不使用鴨子類(lèi)型的語(yǔ)言中,我們可以編寫(xiě)一個(gè)函數(shù),它接受一個(gè)類(lèi)型為鴨的對(duì)象,并調(diào)用它的走和叫方法。在使用鴨子類(lèi)型的語(yǔ)言中,這樣的一個(gè)函數(shù)可以接受一個(gè)任意類(lèi)型的對(duì)象,并調(diào)用它的走和叫方法。

鴨子類(lèi)型通常得益于不測(cè)試方法和函數(shù)中參數(shù)的類(lèi)型,而是依賴(lài)文檔、清晰的代碼和測(cè)試來(lái)確保正確使用。從靜態(tài)類(lèi)型語(yǔ)言轉(zhuǎn)向動(dòng)態(tài)類(lèi)型語(yǔ)言的用戶通常試圖添加一些靜態(tài)的(在運(yùn)行之前的)類(lèi)型檢查,從而影響了鴨子類(lèi)型的益處和可伸縮性,并約束了語(yǔ)言的動(dòng)態(tài)特性。

鴨子類(lèi)型比接口更好用。

class TestClass1:
def say(self):
print('我是鴨子1')
class TestClass2:
def say(self):
print('我是鴨子2')
def duck_say(duck):
duck.say()
duck_say(TestClass1()) # 我是鴨子1
duck_say(TestClass2()) # 我是鴨子2

18、getattr()、setattr()和delattr():

getattr()和 setattr()函數(shù)相應(yīng)地取得和賦值給對(duì)象的屬性,

getattr()會(huì)在你試圖讀取一個(gè)不存在的屬性時(shí),引發(fā) AttributeError 異常,除非給出那個(gè)可選的默認(rèn)參數(shù)。

setattr()將要么加入一個(gè)新的屬性,要么取代一個(gè)已存在的屬性。

delattr()函數(shù)會(huì)從一個(gè)對(duì)象中刪除屬性

class Person(object):
 def __init__(self, name, gender):
 self.name = name
 self.gender = gender
class Student(Person):
 def __init__(self, name, gender, score):
 super(Student, self).__init__(name, gender)
 self.score = score
 def whoAmI(self):
 return 'I am a Student, my name is %s' % self.name
s = Student('Bob', 'Male', 88)
print getattr(s, 'name') # 獲取name屬性 #Bob
setattr(s, 'name', 'Adam') # 設(shè)置新的name屬性
print s.name #Adam
getattr(s, 'age') # 獲取age屬性,但是屬性不存在,報(bào)錯(cuò):
getattr(s, 'age', 20) # 獲取age屬性,如果屬性不存在,就返回默認(rèn)值20:

(9)定制類(lèi)(魔術(shù)方法)

1、__str__():把一個(gè)類(lèi)的實(shí)例變成 str

__repr__()轉(zhuǎn)換為機(jī)器看的字符串,可以由eval()執(zhí)行

class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __str__(self):
return '(Person: %s, %s)' % (self.name, self.gender)
p = Person('Bob', 'male')
print p #(Person: Bob, male)

2、比較運(yùn)算符_cmp__():可以實(shí)現(xiàn)對(duì)一組 Student 類(lèi)的實(shí)例排序

__eq__()判斷等于,__lt__()判斷小于,__gt__()判斷大于

class Student(object):
 def __init__(self, name, score):
 self.name = name
 self.score = score
 def __str__(self):
 return '(%s: %s)' % (self.name, self.score)
 def __cmp__(self, s):
 if self.name < s.name:
 return -1
 elif self.name > s.name:
 return 1
 else:
 return 0
L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 77)]
print sorted(L) #[(Alice: 77), (Bob: 88), (Tim: 99)]
L = [Student('Tim', 99), Student('Bob', 88), 100, 'Hello'] #list不僅僅包含 Student 類(lèi)
print sorted(L) #報(bào)錯(cuò)

上述 Student 類(lèi)實(shí)現(xiàn)了__cmp__()方法,__cmp__用實(shí)例自身self和傳入的實(shí)例 s 進(jìn)行比較,如果self應(yīng)該排在前面,就返回 -1,如果s應(yīng)該排在前面,就返回1,如果兩者相當(dāng),返回 0。

3、__len__():返回元素的個(gè)數(shù)

class Students(object):
def __init__(self, *args):
self.names = args
def __len__(self):
return len(self.names)
ss = Students('Bob', 'Alice', 'Tim')
print len(ss) #3

4、四則運(yùn)算:__add__(),__sub__(),__mul__(),__div__()

邏輯運(yùn)算 __or__(),__and__()

def gcd(a, b):
 if b == 0:
 return a
 return gcd(b, a % b)
class Rational(object):
 def __init__(self, p, q):
 self.p = p
 self.q = q
 def __add__(self, r):
 return Rational(self.p * r.q + self.q * r.p, self.q * r.q)
 def __sub__(self, r):
 return Rational(self.p * r.q - self.q * r.p, self.q * r.q)
 def __mul__(self, r):
 return Rational(self.p * r.p, self.q * r.q)
 def __div__(self, r):
 return Rational(self.p * r.q, self.q * r.p)
 def __str__(self):
 g = gcd(self.p, self.q)
 return '%s/%s' % (self.p / g, self.q / g)
 __repr__ = __str__
r1 = Rational(1, 2)
r2 = Rational(1, 4)
print r1 + r2 #3/4
print r1 - r2 #1/4
print r1 * r2 #1/8
print r1 / r2 #2/1

我們也許還有希望覆蓋“原位”操作, 比如, __iadd__()。這是用來(lái)支持像 mon += tue 這樣的操作符,并把正確的結(jié)果賦給 mon。重載一個(gè)__i*__()方法的唯一秘密是它必須返回 self。把下面的片斷加到我們例子中,以修復(fù)上面的 repr()問(wèn)題,并支持增量賦值:

5、類(lèi)型轉(zhuǎn)換:__int__(),__float__()

class Rational(object):
def __init__(self, p, q):
self.p = p
self.q = q
def __int__(self):
return self.p // self.q
def __float__(self):
return float(self.p) / self.q
print int(Rational(7, 2)) #3
print int(Rational(1, 3)) #0
print float(Rational(7, 2)) #3.5
print float(Rational(1, 3)) #0.333333333333

6、__slots__():限制當(dāng)前類(lèi)所能擁有的屬性,能節(jié)省內(nèi)存

class Person(object):
 __slots__ = ('name', 'gender')
 def __init__(self, name, gender):
 self.name = name
 self.gender = gender
p = Person('Bob', 'male')
print p.name #Bob
print p.gender #male
print p.score #報(bào)錯(cuò)
class Student(Person):
 __slots__ = ('score',)
 def __init__(self, name, gender, score):
 super(Student, self).__init__(name, gender)
 self.score = score
s = Student('Bob', 'male', 59)
print s.score # 59

__slots__定義的屬性僅對(duì)當(dāng)前類(lèi)起作用,對(duì)繼承的子類(lèi)是不起作用的。除非在子類(lèi)中也定義__slots__

7、__call__():

在Python中,所有的函數(shù)都是可調(diào)用對(duì)象。

一個(gè)類(lèi)實(shí)例也可以變成一個(gè)可調(diào)用對(duì)象,只需要實(shí)現(xiàn)一個(gè)特殊方法__call__()。

class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print 'My name is %s...' % self.name
print 'My friend is %s...' % friend
p = Person('Bob', 'male')
p('Tim')
# My name is Bob...
# My friend is Tim...

單看p('Tim')你無(wú)法確定p是一個(gè)函數(shù)還是一個(gè)類(lèi)實(shí)例,所以,在Python中,函數(shù)也是對(duì)象,對(duì)象和函數(shù)的區(qū)別并不顯著。

(10)日期和時(shí)間

1、time包基于C語(yǔ)言的庫(kù)函數(shù)(library functions)。Python的解釋器通常是用C編寫(xiě)的,Python的一些函數(shù)也會(huì)直接調(diào)用C語(yǔ)言的庫(kù)函數(shù)。

2、時(shí)間間隔是以秒為單位的浮點(diǎn)小數(shù)。

3、每個(gè)時(shí)間戳都以自從1970年1月1日午夜(歷元)經(jīng)過(guò)了多長(zhǎng)時(shí)間來(lái)表示。

import time; # 引入time模塊
ticks = time.time()
print ticks

4、獲取當(dāng)前時(shí)間

import time
localtime = time.localtime(time.time())
print '本地時(shí)間為 :', localtime
#本地時(shí)間為 : time.struct_time(tm_year=2017, tm_mon=2, tm_mday=13, tm_hour=22, tm_min=20, tm_sec=59, tm_wday=0, tm_yday=44, tm_isdst=0)
#時(shí)間元組struct_time:年,月,日,小時(shí),分鐘,秒,一周第幾天(0是周一),一年第幾天,夏令時(shí)

5、獲取格式化時(shí)間

最簡(jiǎn)單的獲取可讀的時(shí)間模式的函數(shù)是asctime():

import time
localtime = time.asctime( time.localtime(time.time()) )
print '本地時(shí)間為 :', localtime
#本地時(shí)間為 : Mon Feb 13 22:23:57 2017

我們可以使用 time 模塊的 strftime 方法來(lái)格式化日期:

import time
# 格式化成2016-03-20 11:45:39形式
print time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
#2017-02-13 22:25:08
# 格式化成Sat Mar 28 22:24:24 2016形式
print time.strftime('%a %b %d %H:%M:%S %Y', time.localtime())
#Mon Feb 13 22:25:08 2017
# 將格式字符串轉(zhuǎn)換為時(shí)間戳
a = 'Sat Mar 28 22:24:24 2016'
print time.mktime(time.strptime(a, '%a %b %d %H:%M:%S %Y'))
#1459175064.0

python中時(shí)間日期格式化符號(hào):

%y 兩位數(shù)的年份表示(00-99)

%Y 四位數(shù)的年份表示(000-9999)

%m 月份(01-12)

%d 月內(nèi)中的一天(0-31)

%H 24小時(shí)制小時(shí)數(shù)(0-23)

%I 12小時(shí)制小時(shí)數(shù)(01-12)

%M 分鐘數(shù)(00=59)

%S 秒(00-59)

%a 本地簡(jiǎn)化星期名稱(chēng)

%A 本地完整星期名稱(chēng)

%b 本地簡(jiǎn)化的月份名稱(chēng)

%B 本地完整的月份名稱(chēng)

%j 年內(nèi)的一天(001-366)

%U 一年中的星期數(shù)(00-53)星期天為星期的開(kāi)始

%w 星期(0-6),星期天為星期的開(kāi)始

%W 一年中的星期數(shù)(00-53)星期一為星期的開(kāi)始

6、獲取某月日歷

Calendar模塊有很廣泛的方法用來(lái)處理年歷和月歷,例如打印某月的月歷:

import calendar
cal = calendar.month(2017, 2)
print '以下輸出2017年2月份的日歷:'
print cal
以下輸出2017年2月份的日歷:
# February 2017
# Mo Tu We Th Fr Sa Su
# 1 2 3 4 5
# 6 7 8 9 10 11 12
# 13 14 15 16 17 18 19
# 20 21 22 23 24 25 26
# 27 28

7、time.sleep(secs):推遲調(diào)用線程的運(yùn)行,secs指秒數(shù)。

import time
print('start')
time.sleep(3) # sleep for 3 seconds
print('wake up')

8、datetime包

datetime包是基于time包的一個(gè)高級(jí)包, 為我們提供了多一層的便利。

datetime可以理解為date和time兩個(gè)組成部分。date是指年月日構(gòu)成的日期(相當(dāng)于日歷),time是指時(shí)分秒微秒構(gòu)成的一天24小時(shí)中的具體時(shí)間(相當(dāng)于手表)。

import datetime
t = datetime.datetime(2017,2,13,21,30)
print(t)#2017-02-13 21:30:00

datetime包還定義了時(shí)間間隔對(duì)象(timedelta)。一個(gè)時(shí)間點(diǎn)(datetime)加上一個(gè)時(shí)間間隔(timedelta)可以得到一個(gè)新的時(shí)間點(diǎn)(datetime)。同理,兩個(gè)時(shí)間點(diǎn)相減會(huì)得到一個(gè)時(shí)間間隔。

import datetime
t = datetime.datetime(2017,2,13,21,30)
t_next = datetime.datetime(2017,2,13,23,30)
delta1 = datetime.timedelta(seconds = 600)
delta2 = datetime.timedelta(weeks = 3)
print(t + delta1) #2017-02-13 21:40:00
print(t + delta2) #2017-03-06 21:30:00
print(t_next - t) #2:00:00

9、其他模塊:pytz模塊、dateutil模塊

(11)數(shù)學(xué)與隨機(jī)數(shù)

1、math包主要處理數(shù)學(xué)相關(guān)的運(yùn)算。math包定義了兩個(gè)常數(shù):

math.e # 自然常數(shù)e

math.pi # 圓周率pi

2、math包運(yùn)算

math.ceil(x) # 對(duì)x向上取整,比如x=1.2,返回2

math.floor(x) # 對(duì)x向下取整,比如x=1.2,返回1

math.pow(x,y) # 指數(shù)運(yùn)算,得到x的y次方

math.log(x) # 對(duì)數(shù),默認(rèn)基底為e??梢允褂胋ase參數(shù),來(lái)改變對(duì)數(shù)的基地。

math.sqrt(x) # 平方根

3、math包三角函數(shù):

math.sin(x), math.cos(x), math.tan(x), math.asin(x), math.acos(x), math.atan(x)

這些函數(shù)都接收一個(gè)弧度(radian)為單位的x作為參數(shù)。

角度和弧度互換: math.degrees(x), math.radians(x)

4、random包

1) 隨機(jī)挑選和排序

random.choice(seq) # 從序列的元素中隨機(jī)挑選一個(gè)元素

比如random.choice(range(10)) #從0到9中隨機(jī)挑選一個(gè)整數(shù)。

random.sample(seq,k) # 從序列中隨機(jī)挑選k個(gè)元素

random.shuffle(seq) # 將序列的所有元素隨機(jī)排序

2)隨機(jī)生成實(shí)數(shù)

random.random() # 隨機(jī)生成下一個(gè)實(shí)數(shù),它在[0,1)范圍內(nèi)。

random.uniform(a,b) # 隨機(jī)生成下一個(gè)實(shí)數(shù),它在[a,b]范圍內(nèi)。

5、decimal 十進(jìn)制浮點(diǎn)運(yùn)算類(lèi) Decimal

(12)正則表達(dá)式

1、匹配字符串

str.startswith()和str.endswith()

一個(gè)句子結(jié)尾是\n來(lái)結(jié)束的,所以用endswith('’)方法匹配時(shí)要注意傳入的變量帶有\(zhòng)n

或者用切片操作,str[:-1].endswith()

def find(fname):
 f = open(fname,'r+')
 for line in f :
 if line.startswith('this')\ #一個(gè)句子太長(zhǎng)時(shí)使用 \ 符號(hào)來(lái)?yè)Q行
 or line[:-1].endswith('apple'):
 print line
find('test1.txt')
# this is an apple
# this is a pear
# this is a banana
# that is an apple

2、正則表達(dá)式概念

使用單個(gè)字符串來(lái)描述匹配一系列符合某個(gè)句法規(guī)則的字符串,是對(duì)字符串操作的一種邏輯公式,應(yīng)用場(chǎng)景在處理文本和數(shù)據(jù)。

re 模塊使Python語(yǔ)言擁有全部的正則表達(dá)式功能。

3、導(dǎo)入re模塊 #import re

利用re.compile(正則表達(dá)式)返回pattern

利用pattern.match(待匹配字符串)返回match

match.group()返回子串

match.string()返回主串

match.span()返回子串在主串中的位置

import re
str1 = 'this is an apple'
regex = re.compile(r'this') #r' ’內(nèi)的字符不轉(zhuǎn)義
print regex #<_sre.SRE_Pattern object at 0x0000000001D2DDD8>
ma = regex.match(str1)
print ma #<_sre.SRE_Match object at 0x0000000002075510>
print ma.group() #this
print ma.span() #(0, 4)
print ma.string #this is an apple
print ma.re #=regex

4、re.match 嘗試從字符串的開(kāi)始匹配一個(gè)模式。

re.match(pattern, string, flags=0)

pattern 匹配的正則表達(dá)式

string 要匹配的字符串

flags 標(biāo)志位,用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫(xiě), 多行匹配等等

匹配成功re.match方法返回一個(gè)匹配的對(duì)象,否則返回None。

5、group(num)或groups()匹配對(duì)象函數(shù)來(lái)獲取匹配表達(dá)式。

group(num=0)匹配的整個(gè)表達(dá)式的字符串,group()可以一次輸入多個(gè)組號(hào),在這種情況下它將返回一個(gè)包含那些組所對(duì)應(yīng)值的元組。

groups()返回一個(gè)包含所有小組字符串的元組。

6、基本匹配符

①. 匹配任意字符(除了\n),一個(gè)點(diǎn)只是一個(gè)字符

②[…] 匹配字符集 如[a-z][A-Z][0-9][a-zA-Z0-9]

③[^…] 匹配不在[]中的任意字符

④\d 匹配數(shù)字等價(jià)于[0-9]

⑤\D 匹配非數(shù)字

⑥\s 匹配空白,包括空格、制表符、換頁(yè)符等等。等價(jià)于[\f\n\r\t\v]

⑦\(yùn)S 匹配非空白

⑧\w 匹配單詞字符,匹配包括下劃線的任何單詞字符。等價(jià)于[A-Za-z0-9_]

⑨\W 匹配非單詞字符

import re
ma = re.match(r'[\w]','0')
print ma.group()#0
ma = re.match(r'\[[\w]\]','[0]')
print ma.group()#[0]

7、特殊匹配符

①* 匹配前一個(gè)字符0次或無(wú)限次

②+ 匹配前一個(gè)字符1次或無(wú)限次

③? 匹配前一個(gè)字符0次或1次

④{m} 匹配前一個(gè)字符m次

⑤{m,n} 匹配前一個(gè)字符m到n次

⑥*?或+?或?? 匹配模式變?yōu)榉秦澙罚ūM可能減少匹配字符)

import re
ma = re.match(r'[a-zA-Z0-9]*','SAFGAFG')
print ma.group() #SAFGAFG
ma = re.match(r'[a-zA-Z0-9]{3,6}@163.com','SAFGFG@163.com')
print ma.group() #SAFGFG@163.com
ma = re.match(r'[0-9][a-z]*','1bc')
print ma.group() #1bc
ma = re.match(r'[0-9][a-z]*?','1bc')
print ma.group() #1

8、高級(jí)匹配符

①^ 匹配字符串開(kāi)頭

②$ 匹配字符串結(jié)尾

③\A 指定的字符串必須出現(xiàn)在開(kāi)頭

④\Z 指定的字符串必須出現(xiàn)在結(jié)尾

⑤| 或,匹配左右任意一個(gè)表達(dá)式

⑥(ab) 括號(hào)中表達(dá)式作為一個(gè)分組

⑦\(yùn)<number> 引用編號(hào)為num的分組匹配到的字符串

⑧(?P<name>) 分組起一個(gè)別名

⑨(?P=name) 引用別名為name的分組匹配字符串

import re
ma = re.match(r'^[\w]{4,10}@163.com$','abc123@163.com')
print ma.group() #abc123@163.com
ma = re.match(r'\Aabc[\w]*','abc123')
print ma.group() #abc123
ma = re.match(r'[1-9]?\d$','99')#0-99
print ma.group() #99
ma = re.match(r'[1-9]?\d$|100','100')#0-99
print ma.group() #100
ma = re.match(r'[\w]{4,6}@(163|126|qq).com','abc123@qq.com')
print ma.group() #abc123@qq.com
ma = re.match(r'<([\w]+&gt;)[\w]+</\1','<book>python</book>')
print ma.group() #<book>python</book>
ma = re.match(r'<(?P<mark>[\w]+&gt;)[\w]+</(?P=mark)','<book>python</book>')
print ma.group() #<book>python</book>
ma = re.match(r'<(?P<ht>[\w]+&gt;)<(?P<h>[\w]+&gt;)<(?P<s>[\w]+&gt;).+</(?P=s)</(?P=h)</(?P=ht)','<html><head><script>javascript:alect('hello world')</script></head></html>')
print ma.group() #<html><head><script>javascript:alect('hello world')</script></head></html>
print ma.groups() #('html>', 'head>', 'script>')

9、其他方式

①search(pattern,string,flags=0)

會(huì)在字符串內(nèi)查找模式匹配,直到找到第一個(gè)匹配

匹配成功re.search方法返回一個(gè)匹配的對(duì)象,否則返回None

②findall(pattern,string,flags=0)

找到匹配,返回所有匹配部分的列表

③sub(pattern,repl,string,count=0,flags=0)

將字符串中匹配正則表達(dá)式的部分替換為其他值

④split(pattern,string,maxsplit=0,flags=0)

根據(jù)匹配分割字符串,返回分割字符串組成的列表

import re
str1 = 'abc = 100'
info = re.search(r'\d+',str1)
print info.group() #100
str2 = 'c++=100,java=90,python=80'
info = re.search(r'\d+',str2)
print info.group() #100
info = re.findall(r'\d+',str2)
print info #['100', '90', '80']
print sum([int(x) for x in info]) #270 #列表解析
str3 = 'python video = 1000'
info = re.sub(r'\d+','1001',str3) #sub是調(diào)用findall而不是search
print info #python video = 1001
def add3(match):
 val = match.group()
 num = int(val)+3
 return str(num)
info = re.sub(r'\d+',add3,str3)
print info #python video = 1001
str4 = 'class:C C++ JAVA Python C#'
info = re.split(r':| |,',str4)
print info #['class', 'C', 'C++', 'JAVA', 'Python', 'C#']

10、修飾符

正則表達(dá)式可以包含一些可選標(biāo)志修飾符來(lái)控制匹配的模式。修飾符被指定為一個(gè)可選的標(biāo)志。多個(gè)標(biāo)志可以通過(guò)按位 OR(|) 它們來(lái)指定。

①re.I 使匹配對(duì)大小寫(xiě)不敏感

②re.M 多行匹配,影響 ^和$

③re.S 使.匹配包括換行在內(nèi)的所有字符

11、抓取網(wǎng)頁(yè)中的圖片到本地

1:抓取網(wǎng)頁(yè)

2:獲取圖片地址

3:抓取圖片內(nèi)容并保存到本地

import urllib2,re
req = urllib2.urlopen('http://www.imooc.com/course/list')
buf = req.read()
listurl = re.findall(r'http:.+\.jpg',buf)
i = 0
for url in listurl:
f = open(str(i)+'.jpg','wb')
req = urllib2.urlopen(url)
buf = req.read()
f.write(buf)
i+=1
print I #看看輸出了多少個(gè),此時(shí)也生成i個(gè).jpg

目前python的主要領(lǐng)域

  1. WEB開(kāi)發(fā)——最火的Python web框架Django, 支持異步高并發(fā)的Tornado框架,短小精悍的flask,bottle, Django官方的標(biāo)語(yǔ)把Django定義為the framework for perfectionist with deadlines(大意是一個(gè)為完全主義者開(kāi)發(fā)的高效率web框架)

  2. 網(wǎng)絡(luò)編程——支持高并發(fā)的Twisted網(wǎng)絡(luò)框架, py3引入的asyncio使異步編程變的非常簡(jiǎn)單

  3. 爬蟲(chóng)——爬蟲(chóng)領(lǐng)域,Python幾乎是霸主地位,Scrapy\Request\BeautifuSoap\urllib等,想爬啥就爬啥

  4. 云計(jì)算——目前最火最知名的云計(jì)算框架就是OpenStack,Python現(xiàn)在的火,很大一部分就是因?yàn)樵朴?jì)算

  5. 人工智能——誰(shuí)會(huì)成為AI 和大數(shù)據(jù)時(shí)代的第一開(kāi)發(fā)語(yǔ)言?這本已是一個(gè)不需要爭(zhēng)論的問(wèn)題。如果說(shuō)三年前,Matlab、Scala、R、Java 和 Python還各有機(jī)會(huì),局面尚且不清楚,那么三年之后,趨勢(shì)已經(jīng)非常明確了,特別是前兩天 Facebook 開(kāi)源了 PyTorch 之后,Python 作為 AI 時(shí)代頭牌語(yǔ)言的位置基本確立,未來(lái)的懸念僅僅是誰(shuí)能坐穩(wěn)第二把交椅。

  6. 自動(dòng)化運(yùn)維——問(wèn)問(wèn)中國(guó)的每個(gè)運(yùn)維人員,運(yùn)維人員必須會(huì)的語(yǔ)言是什么?10個(gè)人相信會(huì)給你一個(gè)相同的答案,它的名字叫Python

  7. 金融分析——我個(gè)人之前在金融行業(yè),10年的時(shí)候,我們公司寫(xiě)的好多分析程序、高頻交易軟件就是用的Python,到目前,Python是金融分析、量化交易領(lǐng)域里用的最多的語(yǔ)言

  8. 科學(xué)運(yùn)算—— 你知道么,97年開(kāi)始,NASA就在大量使用Python在進(jìn)行各種復(fù)雜的科學(xué)運(yùn)算,隨著NumPy, SciPy, Matplotlib, Enthought librarys等眾多程序庫(kù)的開(kāi)發(fā),使的Python越來(lái)越適合于做科學(xué)計(jì)算、繪制高質(zhì)量的2D和3D圖像。和科學(xué)計(jì)算領(lǐng)域最流行的商業(yè)軟件Matlab相比,Python是一門(mén)通用的程序設(shè)計(jì)語(yǔ)言,比Matlab所采用的腳本語(yǔ)言的應(yīng)用范圍更廣泛

  9. 游戲開(kāi)發(fā)——在網(wǎng)絡(luò)游戲開(kāi)發(fā)中Python也有很多應(yīng)用。相比Lua or C++,Python 比 Lua 有更高階的抽象能力,可以用更少的代碼描述游戲業(yè)務(wù)邏輯,與 Lua 相比,Python 更適合作為一種 Host 語(yǔ)言,即程序的入口點(diǎn)是在 Python 那一端會(huì)比較好,然后用 C/C++ 在非常必要的時(shí)候?qū)懸恍U(kuò)展。Python 非常適合編寫(xiě) 1 萬(wàn)行以上的項(xiàng)目,而且能夠很好地把網(wǎng)游項(xiàng)目的規(guī)??刂圃?10 萬(wàn)行代碼以內(nèi)。另外據(jù)我所知,知名的游戲<文明> 就是用Python寫(xiě)的

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
python開(kāi)發(fā)總結(jié)
Python裝飾器和符號(hào)@ | Hom
史上最細(xì)致講解!Python 5大常用魔術(shù)方法,一學(xué)就會(huì)
Python裝飾器進(jìn)階
Python實(shí)戰(zhàn)教程:修飾器精講?。?019下半年篇)
適合Java開(kāi)發(fā)者學(xué)習(xí)的Python入門(mén)教程
更多類(lèi)似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服