日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

【python】速查手册(基础笔记) - 人生苦短,我用python

發(fā)布時(shí)間:2023/12/9 python 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【python】速查手册(基础笔记) - 人生苦短,我用python 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
python學(xué)習(xí)筆記:小甲魚(yú)python全套視頻 ?+ ?python基礎(chǔ)教程 第2版修訂版(書(shū)附10個(gè)大型案例)
python學(xué)習(xí)環(huán)境:(python3)win10下python3.5.4的IDLE ?+ ?ubuntu下python3輔助
python分享范圍:適合有C/C++/JAVA任意語(yǔ)言之一為基礎(chǔ),不適合純新手入門(mén)
python語(yǔ)言優(yōu)勢(shì):至今還沒(méi)有一門(mén)編程語(yǔ)言,開(kāi)發(fā)速度比Python快,運(yùn)行速度比C快

python常用工具手冊(cè):
http://bbs.fishc.com/forum.php?mod=collection&action=view&ctid=198

---------------------------------2017.08.27--------------------------------------
00丶python背景與特點(diǎn)
Python語(yǔ)言起源
在1989年末,Guido van Rossum為了打發(fā)圣誕節(jié)的無(wú)聊,創(chuàng)造了python(大蟒蛇)。 1991年,第一個(gè) Python 版本誕生。最新版本是Python3 3.6.2 。Guido van Rossum 是蒙提·派森的飛行馬戲團(tuán)(Monty Python‘s Flying Circus)的愛(ài)好者。logo是由兩只蟒蛇的圖形組成。


官網(wǎng)下載地址:
https://www.python.org/downloads/


Python 3 與 Python 2 不完全兼容
官方表示對(duì) Python2 支持到2020年, Python2 2.7.13。Python 2 的生態(tài)庫(kù)遠(yuǎn)遠(yuǎn)大于 Python 3。


簡(jiǎn)單:
學(xué)習(xí)曲線平滑, 45分鐘學(xué)會(huì)基本使用,使用簡(jiǎn)單。
跨平臺(tái):
一次編寫(xiě)、到處運(yùn)行。 Windows, Linux, Mac, Android
功能強(qiáng)大:
? ? 動(dòng)態(tài)類型、自動(dòng)內(nèi)存管理
? ? 非常實(shí)用的內(nèi)置對(duì)象類型
? ? 強(qiáng)大的內(nèi)置工具和標(biāo)準(zhǔn)庫(kù)
? ? 易于擴(kuò)展,很多成熟易用第三方庫(kù)
? ? 大型程序支持
應(yīng)用廣泛:
? ? 數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)、圖形圖像、科學(xué)計(jì)算、機(jī)器學(xué)習(xí)、web開(kāi)發(fā)、操作系統(tǒng)擴(kuò)展等
缺點(diǎn):
運(yùn)行速度不夠快(硬件的發(fā)展可以為此彌補(bǔ)不足)
開(kāi)發(fā)速度與運(yùn)行速度之間的矛盾:
至今還沒(méi)有一門(mén)編程語(yǔ)言,開(kāi)發(fā)速度比Python快,運(yùn)行速度比C快
知名軟件包:Django/Numpy/Pandas/Matplotlib/PIL (Pillow)/PyQt5/Tensorflow/Scipy/Theano/NLTK
知名項(xiàng)目:(網(wǎng)站)豆瓣/知乎/美團(tuán)/Gmail/Youtube/Instagram/Calibre/……


01丶第一次親密接觸 first love
(1) win下的python IDLE集成開(kāi)發(fā)環(huán)境自動(dòng)縮進(jìn),table鍵補(bǔ)齊變量名
(2) linux下使用vi編輯.py的python文件,需要聲明 #!/usr/bin/python3
(3) python使用等量(1個(gè)tab)的縮進(jìn)來(lái)嚴(yán)格對(duì)齊表示作用域
#!/usr/bin/python3
#guess game


print ("---------游戲開(kāi)始-----------")
temp = input ("輸入一個(gè)我現(xiàn)在想的數(shù)字:")
guess = int (temp)
if guess == 8:
print ("猜對(duì)了!!!")
else:
print ("哈哈,猜錯(cuò)了。。")
print ("游戲結(jié)束嘍~")
#---end---


BIF == Built-in functions(內(nèi)置函數(shù))
>>> dir(__builtins__)
..., 'input', ...
>>> help(input)
#可以查詢內(nèi)置函數(shù)的說(shuō)明和用法,類似于C語(yǔ)言的man手冊(cè)


02丶變量 variable
(1) python沒(méi)有"變量"只有"名字"
(2) 變量使用之前,需要對(duì)其先賦值
(3) 變量名命名同C的規(guī)則,不能以數(shù)字開(kāi)頭,保證可讀性命名即可
(4) 大小寫(xiě)敏感,區(qū)分
(5) =左右依次為左值和右值
(6) 十六進(jìn)制,以0x 或 0X 開(kāi)頭 ,數(shù)字由"0"到"9" 或者 "a"到"f" 或者 "A"到"F"組成
八進(jìn)制,0o或0O 開(kāi)頭,數(shù)字由"0" 到 "7"組成
二進(jìn)制,0b或0B 開(kāi)頭表示,數(shù)字由"0" 或者"1"組成
十進(jìn)制由數(shù)字"0"到"9"組成,并且不能以0開(kāi)頭
>>> teacher = 'jiangyuan'
>>> print (teacher)
jiangyuan
>>> teacher = 'somebody'
>>> print (teacher)
somebody
>>> first = 3
>>> second = 8
>>> third = first + second
>>> print (third)
11
>>> myteacher = 'jiangyuan'
>>> yourteacher = 'somebody'
>>> ourteacher = myteacher + yourteacher
>>> print (ourteacher)
jiangyuansomebody


03丶運(yùn)算符及優(yōu)先級(jí) precedence of operator
#符合數(shù)學(xué)運(yùn)算優(yōu)先原則,括號(hào)最優(yōu)先,最安全。
lambda lambda表達(dá)式
or 布爾或
and 布爾與
not 布爾非
in 和 not in 成員是否屬于測(cè)試
is 和 is not 對(duì)象是否是同一個(gè)
> ?>= ?< ?<= ?== ?!= 比較操作符
| 按位或
^ 按位異或
& 按位與
<< 和 >> 移位
+ 和 - 加法和減法
* 和 / 和 % 乘法、除法、取余
+x 和 -x 正負(fù)號(hào)
~x 按位翻轉(zhuǎn)
** 指數(shù)(冪運(yùn)算)
// 地板除法,舍棄小數(shù)部分
---python運(yùn)算符優(yōu)先級(jí)(圖)---
#=連續(xù)賦值,自右向左,同C語(yǔ)言
>>> a = b = c = d = 10
>>> print (a, b, c, d)
10 10 10 10
>>> a += 1
>>> b -= 1
>>> c *= 10
>>> d /= 8 #真除法,精確值
>>> print (a, b, c, d)
11 9 100 1.25
>>> d = 10
>>> d // 3 ?#地板除法(Floor)舍棄小數(shù)部分
3
>>> 3 < 4 < 5 ?#支持連續(xù)判斷,不建議這樣用,可讀性不高
True
>>> 3 < 4 and 4 < 5
True


04丶類型 type
數(shù)值類型:整型(int)、浮點(diǎn)型(float)、布爾類型(bool)、e記法(科學(xué)計(jì)數(shù)法,屬于float)
(1) 整型與浮點(diǎn)型的區(qū)別就是是否含有小數(shù)點(diǎn)'.'
(2) bool類型的值是以大寫(xiě)開(kāi)頭的兩個(gè)單詞: True / False
(3) 純數(shù)字的字符串可以使用int轉(zhuǎn)為數(shù)字,進(jìn)而參與計(jì)算,相當(dāng)于C的atoi,非純數(shù)字的不能使用int轉(zhuǎn)換為數(shù)字
(4) float類型轉(zhuǎn)換為int類型時(shí),會(huì)丟棄小數(shù)部分
(5) str類型均可被其他類型轉(zhuǎn)換,即變成字符串無(wú)障礙
(6) type (value) 返回變量類型,isinstance(value, type)類型判斷返回bool值


#float→int,丟棄小數(shù)部分
>>> a = 5.99
>>> b = int (a)
>>> print (b)
5


#e記法示例
>>> 0.00000000000000111
1.11e-15
>>> 150000000000
150000000000
>>> 15e10
150000000000.0


#isinstance類型判斷
>>> isinstance ('hello', str)
True
>>> isinstance (520, str)
False
>>> isinstance (520, int)
True


05丶條件分支與循環(huán) condition and loop
條件bool值: True ?False
False 的值: False ?None ?0 ?"" ?() ?[] ?{}


if-else
if condition:
#condition == True, 執(zhí)行的操作,可多層嵌套
else:
#condition == False, 執(zhí)行的操作,可多層嵌套


if-elif-else
if condition:
#condition == True, 執(zhí)行的操作,可多層嵌套
elif condition:
#condition == True, 執(zhí)行的操作,可多層嵌套
else:
#condition == False, 執(zhí)行的操作,可多層嵌套


x if condition else y ?#三元操作符
舉例:
>>> x, y = 4, 5
>>> small = x if x < y else y
>>> print (small)
4


assert 斷言
當(dāng)assert關(guān)鍵字后面的條件為假的時(shí)候,程序自動(dòng)崩潰并拋出AssertionError異常。
>>> assert 3 > 4
Traceback (most recent call last):
? File "<pyshell#160>", line 1, in <module>
? ? assert 3 > 4
AssertionError
>>> assert 3 < 4
>>>?


while 循環(huán)
while condition:
#condition == true, 執(zhí)行的循環(huán)體操作
#condition == false, 循環(huán)體外的操作


for 循環(huán)
for target in expression:
#循環(huán)體
示例:
>>> favourite = 'string'
>>> for i in favourite:
print (i, end=' ') ?#end以空格隔開(kāi)
s t r i n g


range()函數(shù)
range ([start], [stop], [step]) ?#step默認(rèn)每次遞增1,且range的取值范圍到stop-1
常與for循環(huán)一起使用。
示例:
>>> for i in range (2, 5):
print (i, end=' ')
2 3 4
>>> for i in range (1, 10, 2):
print (i, end=' ')
1 3 5 7 9


break 和 continue
同C語(yǔ)言的break和continue,依次為跳出循環(huán)和跳過(guò)當(dāng)前循環(huán)。


pass 和 del 和 exec
pass 什么也不敢,暫時(shí)預(yù)留
del 刪除不再使用的對(duì)象
exec 執(zhí)行python語(yǔ)句
exal 計(jì)算python表達(dá)式,并返回結(jié)果值


06丶列表 list
普通列表:member = ['name', 'id', 'age', 'weight']
混合列表:mix = [1, 'name', 3.14, [1, 2, 3]]
空列表:empty = []
列表常用方法: len()/max()/min()/append()/extend()/insert()/remove()/pop()/count()/index()/reverse()/sort()


len()
功能:列表長(zhǎng)度(元素個(gè)數(shù))
len(listname)
>>> len(member)
4


append()
功能:向列表添加單個(gè)元素
listname.append(element)
>>> member.append('class')
>>> member
['name', 'id', 'age', 'weight', 'class']


extend()
功能:使用子列表擴(kuò)展列表
listname.extend([element1, element2, ...])
>>> member.extend (['str1', 'str2'])
>>> member
['name', 'id', 'age', 'weight', 'class', 'str1', 'str2']


insert()
功能:向列表指定位置插入元素
listname.insert(position, element)
#list和數(shù)組一樣,下標(biāo)/索引均從0開(kāi)始
>>> member.insert (1, 'new_elem')
>>> member
['name', 'new_elem', 'id', 'age', 'weight', 'class', 'str1', 'str2']


列表元素訪問(wèn)
listname[index]
#index從0開(kāi)始,到index-1位置的索引訪問(wèn)


列表元素刪除
listname.remove(element) #刪除元素element
del listname[index] #刪除index位置的元素
listname.pop() #刪除最后一個(gè)元素,相當(dāng)于C語(yǔ)言的彈棧
listname.pop(index) #刪除index位置指定的元素


列表元素分片
listname[start_index:stop_index]
(1) 分片不會(huì)修改原列表的值,輸出的是一份拷貝
(2) 分片輸出的是從 start_index 到 stop_index-1 位置的值
(3) 分片的start和stop位置均可省略,start省略表示從頭取值,stop省略表示取值到結(jié)尾,都省略表示取列表所有的值
示例:
>>> member = ['name', 'id', 'age', 'weight', 'class', 'str1', 'str2', 'str3']
? ? ? ? ? ? ? ?0 ? ? ? 1 ? ? 2 ? ? ?3 ? ? ? ? 4 ? ? ? ?5 ? ? ? 6 ? ? ? 7
>>> member[1:3]
['id', 'age']
>>> member[1:]
['id', 'age', 'weight', 'class', 'str1', 'str2', 'str3']
>>> member[:3]
['name', 'id', 'age']
>>> member[:]
['name', 'id', 'age', 'weight', 'class', 'str1', 'str2', 'str3']
>>> member[5:len(member)] #訪問(wèn)最后3個(gè)元素
['str1', 'str2', 'str3']
>>> member[0:len(member):2] #最后的2代表步長(zhǎng)
['name', 'age', 'class', 'str2']


列表常用操作符
(1) list元素的判斷只會(huì)判斷第一個(gè)元素,然后理解返回bool結(jié)果
(2) list支持比較、邏輯、連接(+)、重復(fù)(*)、成員關(guān)系(in)操作符
(3) list賦值list時(shí)需要注意加上[:],左值會(huì)表現(xiàn)為一份拷貝
示例:
list2 = list1[:]#list2是list1的一份拷貝
list3 = list1 #list3是list1的一個(gè)引用(list1被修改,list3也會(huì)跟著被修改)
(4) dir(list) 查看list支持的所有方法:
listname.count(element)#element元素出現(xiàn)的次數(shù)
listname.index(element, [range_s], [rang_t])#查找元素在起止范圍里第一次出現(xiàn)的下標(biāo)位置
listname.reverse()#將list中的元素原地翻轉(zhuǎn)
listname.sort()#將list中的元素進(jìn)行排序,默認(rèn)從小到大(修改原list內(nèi)容)
listname.sort(reverse=True)#排序元素,實(shí)現(xiàn)從大到小(修改原list內(nèi)容)


07丶元組 tuple
元組和列表使用上相似:
(1) 最大區(qū)別:列表可以任意修改和插入等操作,元組是不可改變的
(2) 創(chuàng)建:列表使用[],元組使用()
元組只有1個(gè)元素時(shí)使用(element,)注意逗號(hào)
()可以省略,但是,逗號(hào)不能省略
(3) 訪問(wèn):都使用name[index]來(lái)訪問(wèn)
(4) 元組在映射中當(dāng)做鍵使用,而列表不行
示例:
>>> temp = 1,
>>> type (temp)
<class 'tuple'>
>>> 8 * (8)
64
>>> 8 * (8,)
(8, 8, 8, 8, 8, 8, 8, 8) ?#重復(fù)元組
#元組元素插入
>>> temp = ('name1','name2','name3','name4')
>>> temp = temp[:2] + ('new_name',) + temp[2:]
>>> temp
('name1', 'name2', 'new_name', 'name3', 'name4')


08丶字符串 ?string
(1) \可以進(jìn)行符號(hào)轉(zhuǎn)義
(2) 單引號(hào)等同于雙引號(hào)
(3) 定義字符串時(shí)使用r寫(xiě)在右值前面聲明為原始字符串
(4) 使用三引號(hào)('''或""")可以指定多行字符串。并且字符串里可以包含單引號(hào)和雙引號(hào)'''
(5) +號(hào)運(yùn)算符可以連接字符串為1個(gè)字符串
(6) *號(hào)運(yùn)算符可以復(fù)制多個(gè)相同字符串
列表和元組應(yīng)用于字符串,所有標(biāo)準(zhǔn)的序列操作均適用于字符串。
>>> str1 = 'hello, python!' ?#字符串相當(dāng)于元素是字符的元組
>>> str1 = str1[:5] + ';' + str1[5:]
>>> str1
'hello;, python!'


字符串常用方法: find()/join()/lower()/replace()/split()/strip()/translate()/
>>> dir(str)
...'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'...
【F1】可以從python的幫助文檔中【索引】查找操作方法的介紹內(nèi)容及舉例。


capitalize() 返回新字符串,把字符串的第一個(gè)字符改為大寫(xiě)
casefold() 返回新字符串,把整個(gè)字符串的所有字符改為小寫(xiě)
center(width) 將字符串居中,并使用空格填充至長(zhǎng)度 width 的新字符串
count(sub[, start[, end]]) 返回 sub 在字符串里邊出現(xiàn)的次數(shù),start 和 end 參數(shù)表示范圍,可選。
encode(encoding='utf-8', errors='strict') 以 encoding 指定的編碼格式對(duì)字符串進(jìn)行編碼。
endswith(sub[, start[, end]]) 檢查字符串是否以 sub 子字符串結(jié)束,如果是返回 True,否則返回 False。start 和 end 參數(shù)表示范圍,可選。
expandtabs([tabsize=8]) 把字符串中的 tab 符號(hào)(\t)轉(zhuǎn)換為空格,如不指定參數(shù),默認(rèn)的空格數(shù)是 tabsize=8。
find(sub[, start[, end]]) 檢測(cè) sub 是否包含在字符串中,如果有則返回索引值,否則返回 -1,start 和 end 參數(shù)表示范圍,可選。
index(sub[, start[, end]]) 跟 find 方法一樣,不過(guò)如果 sub 不在 string 中會(huì)產(chǎn)生一個(gè)異常。
isalnum() 如果字符串至少有一個(gè)字符并且所有字符都是字母或數(shù)字則返回 True,否則返回 False。
isalpha() 如果字符串至少有一個(gè)字符并且所有字符都是字母則返回 True,否則返回 False。
isdecimal() 如果字符串只包含十進(jìn)制數(shù)字則返回 True,否則返回 False。
isdigit() 如果字符串只包含數(shù)字則返回 True,否則返回 False。
islower() 如果字符串中至少包含一個(gè)區(qū)分大小寫(xiě)的字符,并且這些字符都是小寫(xiě),則返回 True,否則返回 False。
isnumeric() 如果字符串中只包含數(shù)字字符,則返回 True,否則返回 False。
isspace() 如果字符串中只包含空格,則返回 True,否則返回 False。
istitle() 如果字符串是標(biāo)題化(所有的單詞都是以大寫(xiě)開(kāi)始,其余字母均小寫(xiě)),則返回 True,否則返回 False。
isupper() 如果字符串中至少包含一個(gè)區(qū)分大小寫(xiě)的字符,并且這些字符都是大寫(xiě),則返回 True,否則返回 False。
join(sub) 以字符串作為分隔符,插入到 sub 中所有的字符之間。
ljust(width) 返回一個(gè)左對(duì)齊的字符串,并使用空格填充至長(zhǎng)度為 width 的新字符串。
lower() 轉(zhuǎn)換字符串中所有大寫(xiě)字符為小寫(xiě)。
lstrip() 去掉字符串左邊的所有空格
partition(sub) 找到子字符串 sub,把字符串分成一個(gè) 3 元組 (pre_sub, sub, fol_sub),如果字符串中不包含 sub 則返回 ('原字符串', '', '')
replace(old, new[, count]) 把字符串中的 old 子字符串替換成 new 子字符串,如果 count 指定,則替換不超過(guò) count 次。
rfind(sub[, start[, end]]) 類似于 find() 方法,不過(guò)是從右邊開(kāi)始查找。
rindex(sub[, start[, end]]) 類似于 index() 方法,不過(guò)是從右邊開(kāi)始。
rjust(width) 返回一個(gè)右對(duì)齊的字符串,并使用空格填充至長(zhǎng)度為 width 的新字符串。
rpartition(sub) 類似于 partition() 方法,不過(guò)是從右邊開(kāi)始查找。
rstrip() 刪除字符串末尾的空格。
split(sep=None, maxsplit=-1) 不帶參數(shù)默認(rèn)是以空格為分隔符切片字符串,如果 maxsplit 參數(shù)有設(shè)置,則僅分隔 maxsplit 個(gè)子字符串,返回切片后的子字符串拼接的列表。
splitlines(([keepends])) 按照 '\n' 分隔,返回一個(gè)包含各行作為元素的列表,如果 keepends 參數(shù)指定,則返回前 keepends 行。
startswith(prefix[, start[, end]]) 檢查字符串是否以 prefix 開(kāi)頭,是則返回 True,否則返回 False。start 和 end 參數(shù)可以指定范圍檢查,可選。
strip([chars]) 刪除字符串前邊和后邊所有的空格,chars 參數(shù)可以定制刪除的字符,可選。
swapcase() 翻轉(zhuǎn)字符串中的大小寫(xiě)。
title() 返回標(biāo)題化(所有的單詞都是以大寫(xiě)開(kāi)始,其余字母均小寫(xiě))的字符串。
translate(table) 根據(jù) table 的規(guī)則(可以由 str.maketrans('a', 'b') 定制)轉(zhuǎn)換字符串中的字符。
upper() 轉(zhuǎn)換字符串中的所有小寫(xiě)字符為大寫(xiě)。
zfill(width) 返回長(zhǎng)度為 width 的字符串,原字符串右對(duì)齊,前邊用 0 填充。


字符串操作:格式化
(1) 通過(guò)format方法將位置參數(shù)傳遞給對(duì)應(yīng)字段
(2) : 冒號(hào)表示格式化符號(hào)的開(kāi)始


位置參數(shù):{0~n}
>>> "{0} love {1},{2}.".format("I", "you", "too")
'I love you,too.'


關(guān)鍵字參數(shù):{自定義}
>>> "{a} love {b}, {c}.".format(a="I", b="you", c="too")
'I love you, too.'
注意:位置參數(shù)和關(guān)鍵字參數(shù)可以同時(shí)使用,但位置參數(shù)必須在關(guān)鍵字參數(shù)的前面。


字符串格式化符號(hào)含義
%c 格式化字符及其 ASCII 碼
%s 格式化字符串
%d 格式化整數(shù)
%o 格式化無(wú)符號(hào)八進(jìn)制數(shù)
%x 格式化無(wú)符號(hào)十六進(jìn)制數(shù)
%X 格式化無(wú)符號(hào)十六進(jìn)制數(shù)(大寫(xiě))
%f 格式化浮點(diǎn)數(shù)字,可指定小數(shù)點(diǎn)后的精度,默認(rèn)精確到小數(shù)點(diǎn)后6位
%e 用科學(xué)計(jì)數(shù)法格式化浮點(diǎn)數(shù)
%E 作用同 %e,用科學(xué)計(jì)數(shù)法格式化浮點(diǎn)數(shù)
%g 根據(jù)值的大小決定使用 %f 或 %e
%G 作用同 %g,根據(jù)值的大小決定使用 %f 或者 %E
舉例:
>>> '%c' % 97 # 此處 % 為占位符,同C語(yǔ)言中printf函數(shù)中的%
'a'
>>> '%c %c %c' % (97, 98, 99) #此處的元組()小括號(hào)不能省略
'a b c'


格式化操作符輔助命令
m.n m 是顯示的最小總寬度,n 是小數(shù)點(diǎn)后的位數(shù)
- 用于左對(duì)齊
+ 在正數(shù)前面顯示加號(hào)(+)
# 在八進(jìn)制數(shù)前面顯示 '0o',在十六進(jìn)制數(shù)前面顯示 '0x' 或 '0X'
0 顯示的數(shù)字前面填充 '0' 取代空格
舉例:
>>> '%5.1f' % 27.658 #m.n
' 27.7'
>>> '%-10d' % 5 #填充的位數(shù)都是空格
'5 ? ? ? ? ?'
>>> '%#x' % 160 #對(duì)應(yīng)進(jìn)制顯示方式
'0xa0'
>>> '%010d' % 5 #用0填充。'%-010d' % 5 負(fù)號(hào)的時(shí)候填充的只會(huì)是空格
'0000000005'


Python 的轉(zhuǎn)義字符及其含義
\' 單引號(hào)
\" 雙引號(hào)
\a 發(fā)出系統(tǒng)響鈴聲
\b 退格符
\n 換行符
\t 橫向制表符(TAB)
\v 縱向制表符
\r 回車符
\f 換頁(yè)符
\o 八進(jìn)制數(shù)代表的字符
\x 十六進(jìn)制數(shù)代表的字符
\0 表示一個(gè)空字符
\\ 反斜杠


09丶序列方法 sequence method
列表、元組、字符串的共同點(diǎn):
(1) 都可以通過(guò)索引得到每一個(gè)元素
(2) 默認(rèn)索引值總是從0開(kāi)始
(3) 可以通過(guò)分片的方法得到一個(gè)范圍內(nèi)的元素的集合
(4) 有很多共同的操作符(重復(fù)*、拼接+、成員關(guān)系in/not in等)
(5) 統(tǒng)稱為序列,以下(成員函數(shù))為序列方法


list()
list(iterable) 把一個(gè)可迭代對(duì)象轉(zhuǎn)換為列表
舉例:
>>> b = 'I love you.' # b也可以是元組 b = (1, 2, 3, 4, 5)
>>> b = list(b)
>>> b
['I', ' ', 'l', 'o', 'v', 'e', ' ', 'y', 'o', 'u', '.']


tuple()
tuple(iterable) 把一個(gè)可迭代對(duì)象轉(zhuǎn)換為元組
舉例:
>>> b = 'I love you.'
>>> b = tuple(b)
>>> b
('I', ' ', 'l', 'o', 'v', 'e', ' ', 'y', 'o', 'u', '.')


max(...) 返回集合或者序列中的最大值(要求類型一致)
min(...) 返回集合或者序列中的最小值(要求類型一致)
>>> max(iterable, *[, default=obj, key=func]) -> value
>>> max(arg1, arg2, *args, *[, key=func]) -> value
舉例:
>>> numbers = [1, 18, 13, 0, -98, 34, 53, 76, 32]
>>> max(numbers)
76
>>> min(numbers)
-98


sum(...) 返回序列iterable和可選參數(shù)的總和(要求類型一致)
>>> sum(iterable, start=0, /)
舉例:
>>> tuple1 = (3.1, 2.3, 3.4)
>>> sum(tuple1)
8.8
>>> sum(tuple1, 0.2) #0.2為可選參數(shù),會(huì)加在一起
9.0


sorted(...) 返回序列的排序結(jié)果
>>> sorted(iterable, /, *, key=None, reverse=False)
舉例:
>>> tuple1 = (3.1, 2.3, 3.4)
>>> sorted(tuple1)
[2.3, 3.1, 3.4]


reversed(...) 翻轉(zhuǎn)一個(gè)序列的內(nèi)容
>>> reversed(sequence)
舉例:
>>> numbers = [1, 24, 5, -98, 54, 32]
>>> reversed(numbers)
<list_reverseiterator object at 0x000002C3EE5046A0>#這種格式都是:迭代器對(duì)象
>>> list(reversed(numbers)) # 將迭代器對(duì)象轉(zhuǎn)換為list列表
[32, 54, -98, 5, 24, 1]


enumerate(...) 生成由序列組成的元組
>>> enumerate(iterable[, start])
舉例:
>>> numbers = [1, 24, 5, -98, 54, 32]
>>> list(enumerate(numbers))
[(0, 1), (1, 24), (2, 5), (3, -98), (4, 54), (5, 32)]


zip(...) 返回由各個(gè)參數(shù)的序列組成的元組
>>> zip(iter1 [,iter2 [...]])
舉例:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> b = [4, 5, 6, 7, 8]
>>> zip(a, b)
<zip object at 0x000002C3EE562948>
>>> list(zip(a, b))
[(1, 4), (2, 5), (3, 6), (4, 7), (5, 8)]
>>> for i,j in zip(a, b): ?#并行迭代,同時(shí)迭代兩個(gè)變量
print(str(i) + ' is ' + str(j))
1 is 4
2 is 5
3 is 6
4 is 7
5 is 8


10丶函數(shù) function
(1) python只有函數(shù)(return)沒(méi)有過(guò)程(no return)
(2) 函數(shù)返回多個(gè)值的時(shí)候,使用list列表或tuple元組進(jìn)行返回
(3) 局部變量和全局變量的規(guī)則同C語(yǔ)言
(4) 在函數(shù)內(nèi)部使用 global 修飾變量,使函數(shù)可以修改同名的全局變量
(5) 函數(shù)嵌套時(shí),內(nèi)部函數(shù)的作用域都在外部函數(shù)之內(nèi),出了外部函數(shù)就不能被調(diào)用


函數(shù)定義和調(diào)用
def function_name():
#函數(shù)體內(nèi)容
function_name() #函數(shù)調(diào)用,執(zhí)行函數(shù)體的內(nèi)容


函數(shù)返回值
def function_name():
#函數(shù)體中返回
return value
print(function_name()) #調(diào)用函數(shù)并打印其返回值


函數(shù)參數(shù)
def function_name(param): #形參:多個(gè)參數(shù)使用,逗號(hào)隔開(kāi)
#函數(shù)體使用參數(shù)param
function_name(parameter) #實(shí)參:傳遞實(shí)際參數(shù)


函數(shù)文檔
舉例:
>>> def my_sec_func(name):
'function document.'#函數(shù)文檔部分,單引號(hào)引起來(lái)即可
print(name)
>>> my_sec_func('myname')
myname
>>> my_sec_func.__doc__ ?#打印輸出函數(shù)文檔部分
'function document.'
>>> help(my_sec_func)
Help on function my_sec_func in module __main__:
my_sec_func(name)
? ? function document.


關(guān)鍵字參數(shù)與默認(rèn)參數(shù)
舉例:
>>> def say_some(name, words):
#>> def say_some(name='abc', words='string'): #形參可設(shè)置默認(rèn)值
print(name + ' -> ' + words)
>>> say_some('Jan', 'learning python.')
Jan -> learning python.
>>> say_some(words='learning python.', name='Jan') #指定形參對(duì)應(yīng)實(shí)參
Jan -> learning python.
#>>> say_some()
#abc -> string


*params搜集其余的位置參數(shù)
>>> def test(*params): # *params把實(shí)參打包為元組
print('len = ', len(params))
print('second params = ', params[1])
>>> test(1, 'Jan', 3.14)
len = ?3
second params = ?Jan
#搜集參數(shù)param加上普通形參
>>> def test(*params, tmp):
print('len = ', len(params))
print('second params = ', params[1])
print('tmp = ', tmp)
>>> test(1, 'Jan', 3.14, tmp = 520) #注意傳參需要單獨(dú)指定
len = ?3
second params = ?Jan
tmp = ?520


global 關(guān)鍵字
舉例:
>>> cnt = 5
>>> def my_func():
global cnt
cnt= 10
print(cnt)
>>> my_func()
10
>>> print(cnt)
10


函數(shù)嵌套
舉例:
>>> def func1():
print('func1 called...')
def func2():
print('func2 called...')
func2()
>>> func1() #調(diào)用func1
func1 called...
func2 called...


閉包c(diǎn)losure
舉例1:
>>> def funX(x):
def funY(y):
return x * y
return funY
>>> i = funX(8)
>>> i
<function funX.<locals>.funY at 0x000001EFE75E87B8>
>>> type(i)
<class 'function'>
>>> i(5)
40
>>> funX(8)(5)
40
>>> funY(5) #不可被調(diào)用,解決辦法有2:list或者nonlocal
舉例2 - list:
>>> def fun1():
x = [5] #對(duì)func2函數(shù)來(lái)說(shuō)x是全局變量,在func2中沒(méi)有定義x,是用list即可安全
def fun2():
x[0] *= x[0]
return x[0]
return fun2()
>>> fun1()
25
舉例2 - nonlocal:
>>> def fun1():
x = 5
def fun2():
nonlocal x #在內(nèi)部函數(shù)中聲明x為非局部變量,再調(diào)用func1()也是安全的
x *= x
return x
return fun2()
>>> fun1()
25


lambda 表達(dá)式(匿名函數(shù))
(1) 不需要考慮函數(shù)名的命名問(wèn)題
(2) 極大簡(jiǎn)化函數(shù)編寫(xiě)的步驟
舉例:
>>> def ds(x):
return 2*x + 1
>>> ds(5)
11
>>> lambda x : 2*x + 1
<function <lambda> at 0x000002170B3D87B8> #可以理解為返回的是C語(yǔ)言的函數(shù)指針
>>> g = lambda x : 2*x + 1 #賦值后,傳參即可,g相當(dāng)于接收了匿名函數(shù)
>>> g(5)
11
>>> g = lambda x, y : x+y #lambda匿名函數(shù)多個(gè)參數(shù)
>>> g(1, 3)
4


兩個(gè)牛逼的BIF:filter和map
(1) filter 過(guò)濾:返回其函數(shù)為真的元素的列表
>>> filter(function or None, iterable)
舉例:
>>> filter(None, [1, 0, False, True])
<filter object at 0x000001CE5BCB0710>
>>> list(filter(None, [1, 0, False, True]))
[1, True] #驗(yàn)證filter過(guò)濾的是非true的內(nèi)容
>>> def odd(x):
return x % 2
>>> temp = range(10)
>>> show = filter(odd, temp)
>>> list(show)
[1, 3, 5, 7, 9]
>>> list(filter(lambda x : x % 2, range(10))) ?#簡(jiǎn)化一行實(shí)現(xiàn)求奇數(shù)
[1, 3, 5, 7, 9]


(2) map 映射:對(duì)序列中每個(gè)元素都應(yīng)用函數(shù)
>>> list(map(lambda x : x + 2, range(10)))
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]




---------------------------------2017.08.28--------------------------------------
11丶遞歸 recursion
#遞歸求階乘:
def factorial(n):
? ? if n == 1:
? ? ? ? return 1 #(1)必須包含退出條件,同C語(yǔ)言
? ? else:
? ? ? ? return n * factorial(n-1) #(2)必須調(diào)用函數(shù)自身,同C語(yǔ)言
number = int(input("請(qǐng)輸入一個(gè)正整數(shù):"))
result = factorial(number)
print("%d 的階乘為:%d" % (number, result))
#運(yùn)行:
請(qǐng)輸入一個(gè)正整數(shù):10
10 的階乘為:3628800


斐波那契數(shù)列(遞歸)
def fab(n):
? ? if n < 1:
? ? ? ? print("input error!")
? ? ? ? return -1
? ? if n == 1 or n == 2:
? ? ? ? return 1
? ? else:
? ? ? ? return fab(n-1) + fab(n-2)
num = int(input("請(qǐng)輸入一個(gè)數(shù)字:"))
result = fab(num)
print("斐波那契數(shù)列結(jié)果為:%d" % result)


漢諾塔游戲(遞歸)
def hanoi(n, x, y, z):
? ? if n == 1:
? ? ? ? print(x, '-->', z)
? ? else:
? ? ? ? hanoi(n-1, x, y, z) ? ? #將前n-1個(gè)盤(pán)子從x移動(dòng)到y(tǒng)上
? ? ? ? print(x, '-->', z) ? ? ?#將最底下的最后一個(gè)盤(pán)子從x移動(dòng)到z上
? ? ? ? hanoi(n-1, y, x, z) ? ? #將y上的n-1個(gè)盤(pán)子移動(dòng)到z上


n = int(input('請(qǐng)輸入漢諾塔的層數(shù):'))
hanoi(n, 'x', 'y', 'z')




---------------------------------2017.08.29--------------------------------------
12丶字典 dict
(1) 字典是一種映射類型(key:value 鍵值映射項(xiàng)),類型名為 dict
(2) 字典的表示使用{}大括號(hào),元素映射之間使用:冒號(hào),使用dictname[]訪問(wèn)字典映射的值
(3) 新建字典有兩種方法:三層小括號(hào),一層小括號(hào)中key=value
(4) 字典中的鍵值映射項(xiàng)是無(wú)序的,popitem時(shí)是隨機(jī)彈出
(5) 字典基本操作:
len(d) 返回d中項(xiàng)的數(shù)量
d[k] 返回映射到鍵k上的值
d[k]=v 將值v映射到鍵k上
del d[k] 刪除鍵為k的項(xiàng)
k in d 檢查d中是否含有鍵為k的項(xiàng)
(6) 字典常用方法: clear()/copy()/fromkeys()/get()/has_key()/items()/iteritems()/keys()/iterkeys()/pop()/popitem()/setdefault()/update()/values()/itervalues()


映射關(guān)系示例
>>> brand = ['李寧', '耐克', '阿迪達(dá)斯', 'xx工作室']
>>> slogan = ['一切皆有可能', 'Just do it', 'Impossible is nothing', '讓編程改變世界']
>>> print('魚(yú)c工作室的口號(hào)是: ', slogan[brand.index('xx工作室')])
xx工作室的口號(hào)是: ?讓編程改變世界
#使用字典來(lái)完成映射工作
>>> dict1 = {'李寧':'一切皆有可能', '耐克':'Just do it', '阿迪達(dá)斯':'Impossible is nothing', 'xx工作室':'讓編程改變世界'}
>>> print('xx工作室的口號(hào)是: ', dict1['xx工作室'])
xx工作室的口號(hào)是: ?讓編程改變世界
#新建一個(gè)字典方法1:dict(((key1, value1), (key2, value2), ...))
>>> dictname = dict((('y', 1), ('u', 2), ('a', 3), ('n', 4)))
>>> dictname
{'u': 2, 'a': 3, 'y': 1, 'n': 4}
#新建一個(gè)字典方法2:(key1=value1, key2=value2, ...)
>>> dictname = dict(蒼井空='讓AV改變宅男', 工作室='讓編程改變世界')
>>> dictname
{'工作室': '讓編程改變世界', '蒼井空': '讓AV改變宅男'}
>>> dictname['蒼井空']
'讓AV改變宅男'
#字典中新增映射元素
>>> dictname['愛(ài)迪生'] = '天才是99%的汗水+1%的靈感,但這1%的靈感比99%的汗水更重要。'
>>> dictname
{'工作室': '讓編程改變世界', '愛(ài)迪生': '天才是99%的汗水+1%的靈感,但這1%的靈感比99%的汗水更重要。', '蒼井空': '讓AV改變宅男'}


字典中鍵、值、鍵值映射項(xiàng)的訪問(wèn)
>>> dict1 = dict1.fromkeys(range(10), '贊')
>>> dict1
{0: '贊', 1: '贊', 2: '贊', 3: '贊', 4: '贊', 5: '贊', 6: '贊', 7: '贊', 8: '贊', 9: '贊'}
>>> for eachKey in dict1.keys():
print(eachKey, end=' ')
0 1 2 3 4 5 6 7 8 9
>>> for eachValue in dict1.values():
print(eachValue, end=' ')
贊 贊 贊 贊 贊 贊 贊 贊 贊
>>> for eachItems in dict1.items():
print(eachItems, end=' ')
(0, '贊') (1, '贊') (2, '贊') (3, '贊') (4, '贊') (5, '贊') (6, '贊') (7, '贊') (8, '贊') (9, '贊')


fromkeys(...) ?創(chuàng)建并返回一個(gè)新的字典
dictname.fromkeys(S[, V])
@S key;@V value 可選參數(shù)
舉例:
>>> dict1 = {}
>>> dict1.fromkeys((1, 2, 3))
{1: None, 2: None, 3: None}
>>> dict1.fromkeys((1, 2, 3), 'number')
{1: 'number', 2: 'number', 3: 'number'}
>>> dict1.fromkeys((1, 2, 3), ('one', 'two', 'three'))
{1: ('one', 'two', 'three'), 2: ('one', 'two', 'three'), 3: ('one', 'two', 'three')}
>>> dict1.fromkeys((1, 3), 'num')
{1: 'num', 3: 'num'} ? #還是返回新的字典,并不會(huì)修改dict1


get(...) ?從字典中找到key的映射值value
舉例:
>>> dict1 = dict.fromkeys(range(10), 'Yes!')
>>> dict1
{0: 'Yes!', 1: 'Yes!', 2: 'Yes!', 3: 'Yes!', 4: 'Yes!', 5: 'Yes!', 6: 'Yes!', 7: 'Yes!', 8: 'Yes!', 9: 'Yes!'}
>>> dict1.get(10)
>>> print(dict1.get(10))
None
>>> dict1.get(10, '木有')
'木有'
>>> dict1.get(9, '木有')
'Yes!'


setdefault(...) ?類似于get但在字典里如果找不到的話會(huì)將映射項(xiàng)添加到字典中
dictname.setdefault(key, value)
舉例:
>>> a
{3: 'three', 4: 'four'}
>>> a.setdefault(5, '小白')
'小白'
>>> a
{3: 'three', 4: 'four', 5: '小白'}


clear() ?清空一個(gè)字典(包括使用當(dāng)前字典賦值的其他字典)
舉例:
>>> dict1.clear()
>>> dict1
{}


copy() ?拷貝一個(gè)字典(淺拷貝,不受字典修改影響)
>>> a = {1:'one', 2:'two', 3:'three'}
>>> b = a.copy()
>>> c = a #相當(dāng)于C的指針,C++的引用,修改字典c的值會(huì)同時(shí)影響字典a
>>> a
{1: 'one', 2: 'two', 3: 'three'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}
>>> c
{1: 'one', 2: 'two', 3: 'three'}
>>> print(id(a), id(b), id(c))
2334673012680 2334672609672 2334673012680
>>> c[4] = 'four'
>>> c
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}


pop(...) ?給定一個(gè)鍵彈出一個(gè)值
popitem() ?隨機(jī)彈出一個(gè)項(xiàng)(映射關(guān)系的鍵和值)
舉例:
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> a.pop(2)
'two'
>>> a
{1: 'one', 3: 'three', 4: 'four'}
>>> a.popitem()
(1, 'one')
>>> a
{3: 'three', 4: 'four'}


update(...) ?使用一個(gè)子字典去更新原字典
dictname1.update(dictname2)
舉例:
>>> a
{3: 'three', 4: 'four', 5: '小白'}
>>> b = {'小白':'狗'}
>>> a.update(b)
>>> a
{'小白': '狗', 3: 'three', 4: 'four', 5: '小白'}


13丶集合 set
(1) 使用{}創(chuàng)建的沒(méi)有映射關(guān)系的字典,成為集合類型,如num = {1, 2, 3, 4, 5}
(2) 集合中元素唯一,重復(fù)的數(shù)據(jù)會(huì)被自動(dòng)清理掉
(3) 集合中元素?zé)o序,不能索引取到其元素的值
(4) 集合使用關(guān)鍵字 set([]) 來(lái)創(chuàng)建
(5) 集合支持 in 和 not in 來(lái)判斷是否屬于集合


舉例:
>>> num = {}
>>> type(num)
<class 'dict'>
#set沒(méi)有體現(xiàn)字典的映射
>>> num1 = {1, 2, 3, 4, 5}
>>> type(num1)
<class 'set'>
#set唯一性
>>> num2 = {1, 2, 3, 4, 2, 3, 5, 1, 5, 5}
>>> num2
{1, 2, 3, 4, 5}
#set無(wú)序性
>>> num2[2]
TypeError: 'set' object does not support indexing
#set關(guān)鍵字創(chuàng)建集合
>>> set1 = set([1, 2, 3, 4, 5, 5, 5, 3, 1])
>>> set1
{1, 2, 3, 4, 5}
#list實(shí)現(xiàn)set的唯一性
>>> num1 = [1, 2, 3, 4, 5, 5, 3, 1, 0]
>>> temp = []
>>> for each in num1:
if each not in temp:
temp.append(each)
>>> temp
[1, 2, 3, 4, 5, 0]
#簡(jiǎn)化: 實(shí)現(xiàn)set的唯一性,并且會(huì)把set的無(wú)序性變?yōu)橛行?br />>>> num1
[1, 2, 3, 4, 5, 5, 3, 1, 0]
>>> num1 = list(set(num1))
>>> num1
[0, 1, 2, 3, 4, 5]


add(...) ?往集合中加入元素
remove(...) ?從集合中刪除指定元素
舉例:
>>> num2
{1, 2, 3, 4, 5}
>>> num2.add(6)
>>> num2
{1, 2, 3, 4, 5, 6}
>>> num2.remove(4)
>>> num2
{1, 2, 3, 5, 6}


frozenset(...) ?將集合設(shè)置為不可變集合,frozen:冰凍的,凍結(jié)的
舉例:
>>> num3 = frozenset([1, 2, 3, 4, 5])
>>> num3
frozenset({1, 2, 3, 4, 5})
>>> num3.add(6)
AttributeError: 'frozenset' object has no attribute 'add'


集合內(nèi)建方法(整理出來(lái)):
http://bbs.fishc.com/forum.php?mod=viewthread&tid=45276&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403


14丶文件操作 file operation
open(...) ?打開(kāi)一個(gè)文件返回一個(gè)流對(duì)象
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) ?#除了file參數(shù),其他參數(shù)均有默認(rèn)值
'r' 只讀模式
'w' 寫(xiě)入(會(huì)覆蓋已存在的文件)模式
'x' 文件存在,報(bào)異常的模式
'a' 寫(xiě)入(文件存在則追加)模式
'b' 二進(jìn)制模式
't' 文本模式
'+' 可讀寫(xiě)模式(可添加到其他模式)
'U' 通用換行符支持


舉例:
#打開(kāi)一個(gè)文件,注意路徑的中\(zhòng)反斜杠的轉(zhuǎn)義(或用/斜杠一根即可)
>>> f = open('C:\\Users\\Jan\\Desktop\\IP.txt')
>>> f
<_io.TextIOWrapper name='C:\\Users\\Jan\\Desktop\\IP.txt' mode='r' encoding='cp936'>


文件對(duì)象方法
(整理)
http://bbs.fishc.com/forum.php?mod=viewthread&tid=45279&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
(1) 文件對(duì)象支持直接使用list轉(zhuǎn)換讀出
(2) 文件對(duì)象支持 for...in 的迭代方式讀取


舉例:
>>> f = open('C:\\Users\\Jan\\Desktop\\IP.txt') #f,打開(kāi)的文件流對(duì)象
>>> f.read()
'【本機(jī)】\nIP:192.168.31.217\n[ Ctrl + r ]\ncmd\nping 192.168.31.207\nmstsc\n\n\n【虛擬機(jī)】 - 虛擬網(wǎng)絡(luò)編輯器(自動(dòng)) - 橋接模式\nIP:192.168.31.207\nlinux賬戶:jiangyuan\nlinux密碼:123456\n'
>>> f.read()
''
>>> f.close()
>>> f = open('C:\\Users\\Jan\\Desktop\\IP.txt')
>>> f.read(5)
'【本機(jī)】\n'
>>> f.tell()
10
>>> f.seek(45, 0) #0,文件起始位置;45,偏移字節(jié)數(shù)。從文件起始位置偏移一定量字節(jié)
45
>>> f.readline()
'md\n'
>>> list(f)
['ping 192.168.31.207\n', 'mstsc\n', '\n', '\n', '【虛擬機(jī)】 - 虛擬網(wǎng)絡(luò)編輯器(自動(dòng)) - 橋接模式\n', 'IP:192.168.31.207\n', 'linux賬戶:jiangyuan\n', 'linux密碼:123456\n']
>>> for each_line in f:
print(each_line)#逐行讀取文件內(nèi)容的高效方法
【本機(jī)】
IP:192.168.31.217
[ Ctrl + r ]
cmd
ping 192.168.31.207
mstsc
...
#創(chuàng)建一個(gè)新的可寫(xiě)入的文件,寫(xiě)入內(nèi)容,然后關(guān)閉文件流對(duì)象
>>> f = open('C:\\Users\\Jan\\Desktop\\test.txt', 'w')
>>> f.write('some lines')
10
>>> f.close()


任務(wù):將文件record.txt中的數(shù)據(jù)進(jìn)行分割并且按照規(guī)律保存起來(lái)。
record.txt下載:
鏈接:http://pan.baidu.com/s/1sjzAhNR (密碼:tf2e)


#最終代碼如下:
def save_file(boy, girl, count):
? ? # 文件的分別保存操作
? ? file_name_boy = 'boy_' + str(count) + '.txt'
? ? file_name_girl = 'girl_' + str(count) + '.txt'


? ? boy_f = open(file_name_boy, 'w')
? ? girl_f = open(file_name_girl, 'w')


? ? boy_f.writelines(boy)
? ? girl_f.writelines(girl)


? ? boy_f.close()
? ? girl_f.close()


def split_file(filename):
? ? f = open(filename)


? ? boy = []
? ? girl = []
? ? count = 1


? ? for each_line in f:
? ? ? ? if each_line[:6] != '======':
? ? ? ? ? ? # 我們?cè)龠@里進(jìn)行字符串分割操作
? ? ? ? ? ? (role, line_spoken) = each_line.split(':', 1) ?#中文冒號(hào):否則會(huì)報(bào)錯(cuò)
? ? ? ? ? ? if role == '小甲魚(yú)':
? ? ? ? ? ? ? ? boy.append(line_spoken)
? ? ? ? ? ? if role == '小客服':
? ? ? ? ? ? ? ? girl.append(line_spoken)
? ? ? ? else:
? ? ? ? ? ? save_file(boy, girl, count)


? ? ? ? ? ? boy = []
? ? ? ? ? ? girl = []
? ? ? ? ? ? count += 1


? ? save_file(boy, girl, count)
? ? f.close()


split_file('C:\\Users\\Jan\\Desktop\\python_study\\record.txt')


文件操作練習(xí)題及答案(偽代碼可以保存一下):
http://blog.csdn.net/junwei0206/article/details/44988195


---------------------------------2017.08.30--------------------------------------
15丶模塊 modules
(1) 模塊是.py的python文件
(2) 使用模塊是需要進(jìn)行導(dǎo)入,使用關(guān)鍵字 import


舉例:
>>> import random
>>> secret = random.randint(1, 10)
>>> secret
3


os 模塊(系統(tǒng)模塊)


os模塊方法表格:http://bbs.fishc.com/thread-45512-1-2.html


舉例:
>>> import os
>>> os.getcwd() ?#輸出當(dāng)前工作目錄
'C:\\Users\\Jan\\AppData\\Local\\Programs\\Python\\Python35'
>>> os.chdir('E:\\') ?#改變工作目錄
>>> os.getcwd()
'E:\\'
>>> os.listdir('E:\\') ?#列舉指定目錄中的文件名
['$RECYCLE.BIN', '.cache', '360Downloads', 'Jan_mi', 'Jan個(gè)人總資料', 'Qiyi', 'QQMusicCache', 'qycache', 'System Volume Information', 'Youku Files', 'Youxun', '博客'] ?#RECYCLE.BIN是個(gè)回收站
>>> os.mkdir('E:\\A') ?#創(chuàng)建單層目錄,如該目錄已存在拋出異常
>>> os.mkdir('E:\\A\\B')
>>> os.mkdir('E:\\C\\D')
FileNotFoundError: [WinError 3] 系統(tǒng)找不到指定的路徑。: 'E:\\C\\D'
>>> os.remove('E:\\A\\B\\test.txt') ?#刪除文件
>>> os.rmdir('E:\\A\\B\\') ?#刪除單層目錄,如該目錄非空則拋出異常
>>> os.system('cmd') ?#運(yùn)行系統(tǒng)的shell命令:windows shell窗口
-1073741510
>>> os.system('calc') ?#運(yùn)行系統(tǒng)的shell命令:calc計(jì)算器
0
>>> os.curdir ?#當(dāng)前目錄('.')
'.'
>>> os.listdir(os.curdir) ?# 等同于 os.listdir('.')
['$RECYCLE.BIN', '.cache', '360Downloads', 'A', 'Jan_mi', 'Jan個(gè)人總資料', 'Qiyi', 'QQMusicCache', 'qycache', 'System Volume Information', 'Youku Files', 'Youxun', '博客']
>>> os.sep ?#輸出操作系統(tǒng)特定的路徑分隔符(Win下為'\\',Linux下為'/')
'\\'
>>> os.linesep ?#當(dāng)前平臺(tái)使用的行終止符(Win下為'\r\n',Linux下為'\n')
'\r\n'
>>> os.name ?#指代當(dāng)前使用的操作系統(tǒng)(包括:'posix', ?'nt', 'mac', 'os2', 'ce', 'java')
'nt' ?#nt是windows系統(tǒng)平臺(tái)


os.path 模塊(系統(tǒng)路徑模塊屬于os的子模塊)
>>> os.path.basename('E:\\A\\B\\C\\sexy.avi') ?#去掉目錄路徑,單獨(dú)返回文件名
'sexy.avi'
>>> os.path.dirname('E:\\A\\B\\C\\sexy.avi') ?#去掉文件名,單獨(dú)返回目錄路徑
'E:\\A\\B\\C'
>>> os.path.join('A', 'B', 'C') ?#將path1, path2...各部分組合成一個(gè)路徑名
'A\\B\\C'
>>> os.path.join('D:', 'A', 'B', 'C')
'D:A\\B\\C'
>>> os.path.join('D:\\', 'A', 'B', 'C') ?#注意盤(pán)符需要帶上斜杠
'D:\\A\\B\\C'
>>> os.path.split('E:\\A\\SEXY.AVI') ?#分割文件名與路徑,返回(f_path, f_name)元組。
('E:\\A', 'SEXY.AVI')
>>> os.path.split('E:\\A\\B\\C')
('E:\\A\\B', 'C')
>>> os.path.splitext('E:\\A\\SEXY.AVI') ?#分離文件名與擴(kuò)展名,返回(f_name, f_extension)元組
('E:\\A\\SEXY', '.AVI')
>>> os.path.getatime('E:\\A\\test.txt') ?#返回指定文件最近的訪問(wèn)時(shí)間
1504103243.229383 ?#浮點(diǎn)型秒數(shù),可用time模塊的gmtime()或localtime()函數(shù)換算
>>> import time
>>> time.gmtime(os.path.getatime('E:\\A\\test.txt'))
time.struct_time(tm_year=2017, tm_mon=8, tm_mday=30, tm_hour=14, tm_min=27, tm_sec=23, tm_wday=2, tm_yday=242, tm_isdst=0)
>>> time.localtime(os.path.getatime('E:\\A\\test.txt'))
time.struct_time(tm_year=2017, tm_mon=8, tm_mday=30, tm_hour=22, tm_min=27, tm_sec=23, tm_wday=2, tm_yday=242, tm_isdst=0)
>>> time.localtime(os.path.getmtime('E:\\A\\test.txt'))
time.struct_time(tm_year=2017, tm_mon=8, tm_mday=30, tm_hour=22, tm_min=30, tm_sec=1, tm_wday=2, tm_yday=242, tm_isdst=0)
>>> time.localtime(os.path.getctime('E:\\A\\test.txt'))
time.struct_time(tm_year=2017, tm_mon=8, tm_mday=30, tm_hour=22, tm_min=27, tm_sec=23, tm_wday=2, tm_yday=242, tm_isdst=0)
>>> os.path.ismount('E:\\') ?#判斷指定路徑是否存在且是一個(gè)掛載點(diǎn)
True
>>> os.path.ismount('E:\\A')
False


pickle 模塊(泡菜模塊)
舉例:
>>> import pickle
>>> my_list = [123, 3.14, '名字', ['another list']]
>>> pickle_f = open('E:\\A\\my_list.pkl', 'wb')
>>> pickle.dump(my_list, pickle_f) ?#將list的內(nèi)容傾倒入文件流對(duì)象中
>>> pickle_f.close()
>>> pickle_f = open('E:\\A\\my_list.pkl', 'rb')
>>> my_list2 = pickle.load(pickle_f) ?#將.pkl文件的內(nèi)容裝載到list中
>>> print(my_list2)
[123, 3.14, '名字', ['another list']]


>>> city = {'城市1':'000001', '城市2':'000002', '城市n':'999999'} ?#此字典映射有70k這么大
>>> import pickle
>>> pickle_f = open('E:\\A\\city.pkl', 'wb') ?#將70k的字典映射寫(xiě)入文件
>>> pickle.dump(city, pickle_f)
>>> pickle_f.close()
>>> pickle_file = open('E:\\A\\city.pkl', 'rb') ?#使用字典的時(shí)候打開(kāi)文件裝載即可
>>> city = pickle.load(pickle_file)
>>> print(city)
{'城市2': '000002', '城市n': '999999', '城市1': '000001'}


---------------------------------2017.08.31--------------------------------------
16丶異常 exception
異常匯總
AssertionError 斷言語(yǔ)句(assert)失敗<eg1>
AttributeError 嘗試訪問(wèn)未知的對(duì)象屬性<eg2>
EOFError 用戶輸入文件末尾標(biāo)志EOF(Ctrl+d)?
FloatingPointError 浮點(diǎn)計(jì)算錯(cuò)誤?
GeneratorExit generator.close()方法被調(diào)用的時(shí)候?
ImportError 導(dǎo)入模塊失敗的時(shí)候?
IndexError 索引超出序列的范圍<eg3>
KeyError 字典中查找一個(gè)不存在的關(guān)鍵字<eg4>
KeyboardInterrupt 用戶輸入中斷鍵(Ctrl+c)?
MemoryError 內(nèi)存溢出(可通過(guò)刪除對(duì)象釋放內(nèi)存)?
NameError 嘗試訪問(wèn)一個(gè)不存在的變量?
NotImplementedError 尚未實(shí)現(xiàn)的方法?
OSError 操作系統(tǒng)產(chǎn)生的異常(例如打開(kāi)一個(gè)不存在的文件)?
OverflowError 數(shù)值運(yùn)算超出最大限制?
ReferenceError 弱引用(weak reference)試圖訪問(wèn)一個(gè)已經(jīng)被垃圾回收機(jī)制回收了的對(duì)象?
RuntimeError 一般的運(yùn)行時(shí)錯(cuò)誤?
StopIteration 迭代器沒(méi)有更多的值?
SyntaxError Python的語(yǔ)法錯(cuò)誤?
IndentationError 縮進(jìn)錯(cuò)誤?
TabError Tab和空格混合使用?
SystemError Python編譯器系統(tǒng)錯(cuò)誤?
SystemExit Python編譯器進(jìn)程被關(guān)閉?
TypeError 不同類型間的無(wú)效操作?
UnboundLocalError 訪問(wèn)一個(gè)未初始化的本地變量(NameError的子類)?
UnicodeError Unicode相關(guān)的錯(cuò)誤(ValueError的子類)?
UnicodeEncodeError Unicode編碼時(shí)的錯(cuò)誤(UnicodeError的子類)?
UnicodeDecodeError Unicode解碼時(shí)的錯(cuò)誤(UnicodeError的子類)?
UnicodeTranslateError Unicode轉(zhuǎn)換時(shí)的錯(cuò)誤(UnicodeError的子類)?
ValueError 傳入無(wú)效的參數(shù)?
ZeroDivisionError 除數(shù)為零?


部分舉例:
>>> my_list = ['我是帥哥', '你是美女']
>>> assert len(my_list) > 0
>>> my_list.pop()
'你是美女'
>>> my_list.pop()
'我是帥哥'
>>> assert len(my_list) > 0
Traceback (most recent call last):
? File "<pyshell#856>", line 1, in <module>
? ? assert len(my_list) > 0
AssertionError #斷言語(yǔ)句(assert)失敗
>>> my_list.abcd
Traceback (most recent call last):
? File "<pyshell#857>", line 1, in <module>
? ? my_list.abcd
AttributeError: 'list' object has no attribute 'abcd'#嘗試訪問(wèn)未知的對(duì)象屬性
>>> my_list = [1, 2, 3]
>>> my_list[3]
Traceback (most recent call last):
? File "<pyshell#859>", line 1, in <module>
? ? my_list[3]
IndexError: list index out of range #索引超出序列的范圍
>>> my_list[2]
3
>>> my_dict = {'one':1, 'two':2, 'three':3}
>>> my_dict['one']
1
>>> my_dict['four']
Traceback (most recent call last):
? File "<pyshell#863>", line 1, in <module>
? ? my_dict['four']
KeyError: 'four' #字典中查找一個(gè)不存在的關(guān)鍵字
>>> my_dict.get('four')
>>> #dict.get(...)方法比較安全合適


異常檢測(cè)與處理
(1) try語(yǔ)句一旦檢測(cè)出現(xiàn)異常,則剩下的其他代碼則不會(huì)執(zhí)行
(2) raise Exception_name 主動(dòng)引發(fā)一個(gè)自定義異常名字的異常,可定義異常描述


try:
#檢測(cè)范圍
except Exception[as reason]:
#出現(xiàn)異常(Exception)后的處理代碼
finally:
#無(wú)論如何都會(huì)被執(zhí)行的代碼(收尾工作)


舉例:
try:
? ? f = open('我為什么是一個(gè)文件.txt')
? ? print(f.read())
? ? f.close()
except OSError:
? ? print('文件出錯(cuò)啦T_T')
運(yùn)行:
文件出錯(cuò)啦T_T


try:
? ? f = open('我為什么是一個(gè)文件.txt')
? ? print(f.read())
? ? f.close()
except OSError as reason:
? ? print('文件出錯(cuò)啦T_T\n錯(cuò)誤的原因是:' + str(reason))
運(yùn)行:
文件出錯(cuò)啦T_T
錯(cuò)誤的原因是:[Errno 2] No such file or directory: '我為什么是一個(gè)文件.txt'


try:
? ? sum = 1 + '1'
? ? f = open('我為什么是一個(gè)文件.txt')
? ? print(f.read())
? ? f.close()
except (OSError, TypeError): ?#多個(gè)異常同時(shí)捕獲
? ? print('出錯(cuò)啦T_T')
運(yùn)行:出錯(cuò)啦T_T


try:
? ? f = open('我為什么是一個(gè)文件.txt', 'w')
? ? print(f.write('我存在了!')) ?#沒(méi)有finally時(shí)并不會(huì)寫(xiě)入文件
? ? sum = 1 + '1'
? ? f.close()
except (OSError, TypeError):
? ? print('出錯(cuò)啦T_T')
finally:
? ? f.close()
運(yùn)行:
5
出錯(cuò)啦T_T


>>> raise ZeroDivisionError('除數(shù)為0的異常')
Traceback (most recent call last):
? File "<pyshell#872>", line 1, in <module>
? ? raise ZeroDivisionError('除數(shù)為0的異常')
ZeroDivisionError: 除數(shù)為0的異常


17丶豐富的esle-簡(jiǎn)潔的with
else


舉例:while-else / for-else
def showMaxFactor(num):
? ? count = num // 2
? ? while count > 1:
? ? ? ? if num % count == 0:
? ? ? ? ? ? print('%d最大的約數(shù)是%d' % (num, count))
? ? ? ? ? ? break
? ? ? ? count -= 1
? ? else: #while循環(huán)完沒(méi)有break就會(huì)執(zhí)行else
? ? ? ? print('%d是素?cái)?shù)!' % num)


num = int(input('請(qǐng)輸入一個(gè)數(shù):'))
showMaxFactor(num)


舉例:try-else
try:
? ? print(int('123'))
except ValueError as reason:
? ? print('出錯(cuò)啦:' + str(reason))
else:
? ? print('Good!沒(méi)有任何異常。')
運(yùn)行:
123
Good!沒(méi)有任何異常。


with as


舉例:
try:
? ? with open('data.txt', 'w') as f: #比 f = open(...) 多了文件不使用時(shí)自動(dòng)關(guān)閉功能
? ? for each_line in f:
? ? ? ? print(each_line)
except OSError as reason:
? ? print('出錯(cuò)啦:' + str(reason))
#finally: ? ? ? #有了with就不需要finally去調(diào)用關(guān)閉,會(huì)自動(dòng)關(guān)閉
# ? ?f.close() ?#如果文件data.txt不存在就試圖去關(guān)閉一個(gè)不存在的文件


18丶圖形用戶界面 EasyGui
EasyGui官網(wǎng):http://easygui.sourceforge.net
中文的教學(xué)文檔:http://bbs.fishc.com/thread-46069-1-1.html (要看完并實(shí)操)
模塊庫(kù):easygui-0.96.zip


安裝方法:
(1) 使用命令窗口切換到easygui-docs-0.96的目錄下
(2) 【W(wǎng)indows下】執(zhí)行C:\Python33\python.exe setup.py install
> cd Desktop
> cd puthon_study\easygui-0.96
#然后修改C:\Program Files (x86)\python\python.exe為管理員權(quán)限:右鍵-兼容性-更改所有用戶的設(shè)置-以管理員身份運(yùn)行此程序-確定
> "C:\Program Files (x86)\python\python.exe" setup.py install
#生成了文件模塊庫(kù)C:\Program Files (x86)\python\Lib\site-packages\easygui.py
> "C:\Program Files (x86)\python\python.exe" easygui.py
#easygui的演示程序
PS: 【Linux或Mac下】sudo /Library/Framworks/Python.framework/Versions/3.3/bin/python3.3 setup.py install


使用方法:
【遇到難題】import easygui 出錯(cuò)~!!!
【解決辦法】
(1) 重裝python IDLE勾選添加python路徑,選擇目錄安裝到C:\python文件夾,如重裝則忽略(2),如此一來(lái)win-cmd下的python中sys.path和IDLE中的sys.path則一致了。
(2) 對(duì)比windows命令窗口中啟動(dòng)python與IDLE中python的系統(tǒng)路徑,添加到IDLE即可。


windows中系統(tǒng)路徑:
C:\Users\Jan> "C:\Program Files (x86)\python\python.exe"
>>> import sys
>>> sys.path
['',?
'C:\\Program Files (x86)\\python\\python35.zip',?
'C:\\Program Files (x86)\\python\\DLLs',?
'C:\\Program Files (x86)\\python\\lib',?
'C:\\Program Files (x86)\\python',?
'C:\\Program Files (x86)\\python\\lib\\site-packages']


IDLE中系統(tǒng)路徑:
>>> import easygui as g
Traceback (most recent call last):
? File "<pyshell#0>", line 1, in <module>
? ? import easygui as g
ImportError: No module named 'easygui'
>>> import sys
>>> sys.path
['',?
'C:\\Users\\Jan\\AppData\\Local\\Programs\\Python\\Python35\\Lib\\idlelib',?
'C:\\Users\\Jan\\AppData\\Local\\Programs\\Python\\Python35\\python35.zip',?
'C:\\Users\\Jan\\AppData\\Local\\Programs\\Python\\Python35\\DLLs',?
'C:\\Users\\Jan\\AppData\\Local\\Programs\\Python\\Python35\\lib',?
'C:\\Users\\Jan\\AppData\\Local\\Programs\\Python\\Python35',?
'C:\\Users\\Jan\\AppData\\Local\\Programs\\Python\\Python35\\lib\\site-packages']
>>> sys.path.append('C:\\Program Files (x86)\\python\\python35.zip')
>>> sys.path.append('C:\\Program Files (x86)\\python\\DLLs')
>>> sys.path.append('C:\\Program Files (x86)\\python\\lib')
>>> sys.path.append('C:\\Program Files (x86)\\python')
>>> sys.path.append('C:\\Program Files (x86)\\python\\lib\\site-packages')
>>> import easygui as g ?#import ... as ... 導(dǎo)入模塊的同時(shí)重定義模塊名字
>>> g.msgbox('嗨,python!')
'OK'
>>>?
# No error, success... 但每次重啟IDLE都需要將windows下的sys.path進(jìn)行添加。


# 示例,gui界面文字小游戲
import easygui as g
import sys


while 1:
? ? ? ? g.msgbox("嗨,歡迎進(jìn)入第一個(gè)界面小游戲^_^")


? ? ? ? msg ="請(qǐng)問(wèn)你希望在魚(yú)C工作室學(xué)習(xí)到什么知識(shí)呢?"
? ? ? ? title = "小游戲互動(dòng)"
? ? ? ? choices = ["談戀愛(ài)", "編程", "OOXX", "琴棋書(shū)畫(huà)"]
? ? ? ??
? ? ? ? choice = g.choicebox(msg, title, choices)


? ? ? ? # note that we convert choice to string, in case
? ? ? ? # the user cancelled the choice, and we got None.
? ? ? ? g.msgbox("你的選擇是: " + str(choice), "結(jié)果")


? ? ? ? msg = "你希望重新開(kāi)始小游戲嗎?"
? ? ? ? title = "請(qǐng)選擇"
? ? ? ??
? ? ? ? if g.ccbox(msg, title): ? ? # show a Continue/Cancel dialog
? ? ? ? ? ? ? ? pass ?# user chose Continue
? ? ? ? else:
? ? ? ? ? ? ? ? sys.exit(0) ? ? # user chose Cancel


---------------------------------2017.09.01--------------------------------------
19丶類和對(duì)象 class and object
面向?qū)ο?Object Oriented)
(1) python約定類名以大寫(xiě)字母開(kāi)頭
(2) 面向?qū)ο筇卣?#xff1a;封裝(信息隱蔽)、繼承(子類共享父類公共內(nèi)容)、多態(tài)(不同對(duì)象對(duì)同一方法響應(yīng)不同的行動(dòng))


類的示例:
class Turtle:
#屬性
color = 'green'
weight = 60
legs = 2
shell = True
age = 26


#方法
def climb(self):
print('我正在學(xué)習(xí)...')
def run(self):
print('我正在奔跑...')


運(yùn)行:
>>> tt = Turtle() ?#類Turtle的示例對(duì)象tt
>>> Turtle
<class '__main__.Turtle'>
>>> type(Turtle)
<class 'type'>
>>> type('abc')
<class 'str'>
>>> tt.climb()
我正在學(xué)習(xí)...
>>> tt.run()
我正在奔跑...


#封裝
>>> list1 = [2, 1, 7, 5, 3]
>>> list1.sort() ?#sort() 方法封裝在list1對(duì)象中
>>> list1
[1, 2, 3, 5, 7]
>>> list1.append(9) ?#append() 方法封裝在list1對(duì)象中
>>> list1
[1, 2, 3, 5, 7, 9]


#繼承
>>> class Mylist(list):
pass
>>> list2 = Mylist()
>>> list2.append(5) ?#list2可以使用append()方法,繼承了Mylist(list)中的list參數(shù)類
>>> list2.append(3)
>>> list2.append(7)
>>> list2
[5, 3, 7]
>>> list2.sort()
>>> list2
[3, 5, 7]


#多態(tài)
>>> class A:
def fun(self):
print('我是小A')
>>> class B:
def fun(self):
print('我是小B')
>>> a = A()
>>> b = B()
>>> a.fun() ?#不同對(duì)象對(duì)同一方法響應(yīng)不同的行動(dòng)
我是小A
>>> b.fun() ?#不同對(duì)象對(duì)同一方法響應(yīng)不同的行動(dòng)
我是小B


self
相當(dāng)于C++的this指針(指向當(dāng)前對(duì)象本身的地址),表明類自身
舉例:
>>> class Ball:
def setName(self, name): ?#默認(rèn)self的寫(xiě)法
self.name = name
def kick(self): ?#默認(rèn)self的寫(xiě)法
print('我叫%s, 該死的誰(shuí)踢我...' % self.name)
>>> a = Ball()
>>> a.setName('球A')
>>> b = Ball()
>>> b.setName('球B')
>>> c = Ball()
>>> c.setName('土豆')
>>> a.kick()
我叫球A, 該死的誰(shuí)踢我...
>>> c.kick()
我叫土豆, 該死的誰(shuí)踢我...


魔法方法:__init__(self)
__init__(self, parma1, parma2, ...)
舉例:
>>> class Ball:
def __init__(self, name):
self.name = name
def kick(self):
print('我叫%s,該死的,誰(shuí)踢我!!' % self.name)
>>> b = Ball('土豆')
>>> b.kick()
我叫土豆,該死的,誰(shuí)踢我!!
>>> a = Ball() ?#__init__默認(rèn)設(shè)置了name,所以必須傳遞name實(shí)參,否則報(bào)錯(cuò)
TypeError: __init__() missing 1 required positional argument: 'name'


公有和私有
name mangling 名字改變/名字重造
公有成員:默認(rèn)創(chuàng)建的成員均為公有。
私有成員:
(1) 在變量或函數(shù)名前加上"_"兩個(gè)下劃線即可。
(2) python中類的私有均屬于偽私有,通過(guò)"對(duì)象._類_變量"的形式可以訪問(wèn)私有成員
舉例:
>>> class Person:
__name = 'yuan.jiang'
>>> p = Person()
>>> p.name
AttributeError: 'Person' object has no attribute 'name'
>>> p.__name
AttributeError: 'Person' object has no attribute '__name'
>>> class Person:
__name = 'yuan.jiang'
def getName(self):
return self.__name
>>> p = Person()
>>> p.getName()
'yuan.jiang'
>>> p._Person__name ?#python中類的私有屬于偽私有,此方式可訪問(wèn)私有成員
'yuan.jiang'


繼承 inherit
class DerivedClassName(BaseClassName):
...
(1) 如果子類中定義于父類同名的成員時(shí),則會(huì)自動(dòng)覆蓋父類對(duì)應(yīng)的方法或?qū)傩?br />(2) 解決子類中__init()


舉例:
>>> class Parent:
def hello(self):
print('正在調(diào)用父類的方法...')
>>> class Child(Parent):
pass
>>> p = Parent()
>>> p.hello()
正在調(diào)用父類的方法...
>>> c = Child()
>>> c.hello()
正在調(diào)用父類的方法...
>>> class Child(Parent):
def hello(self):
print('正在調(diào)用子類的方法...')
>>> c = Child()
>>> c.hello()
正在調(diào)用子類的方法...
>>> p.hello()
正在調(diào)用父類的方法...


舉例:
import random as r
class Fish:
? ? def __init__(self):
? ? ? ? self.x = r.randint(0, 10)
? ? ? ? self.y = r.randint(0, 10)


? ? def move(self):
? ? ? ? self.x -= 1
? ? ? ? print('我的位置是:', self.x, self.y)


class Goldfish(Fish):
? ? pass
class Carpfish(Fish):
? ? pass
class Salmonfish(Fish):
? ? pass
class Sharkfish(Fish):
? ? def __init__(self): ?#重寫(xiě)了__init__方法覆蓋了父類的__init__子類無(wú)法調(diào)用到self.x和self.y屬性成員,導(dǎo)致了子類無(wú)法訪問(wèn)到父類的屬性或方法的問(wèn)題
? ? ? ? self.hungry = True
? ? def eat(self):
? ? ? ? if self.hungry:
? ? ? ? ? ? print('吃貨的夢(mèng)想就是天天有的吃^_^')
? ? ? ? ? ? self.hungry = False
? ? ? ? else:
? ? ? ? ? ? print('太撐了,吃不下了!')
運(yùn)行:
>>> fish = Fish()
>>> fish.move()
我的位置是: 3 0
>>> fish.move()
我的位置是: 2 0
>>> goldfish = Goldfish()
>>> goldfish.move()
我的位置是: 4 9
>>> goldfish.move()
我的位置是: 3 9
>>> shark = Sharkfish()
>>> shark.eat()
吃貨的夢(mèng)想就是天天有的吃^_^
>>> shark.eat()
太撐了,吃不下了!
>>> shark.move() ?#無(wú)法訪問(wèn)到父類的__init__()方法中的x變量
AttributeError: 'Sharkfish' object has no attribute 'x'


--------------------------------2017.09.02----------------------------------------


覆蓋屬性或方法問(wèn)題優(yōu)化
問(wèn)題:針對(duì)子類屬性或方法覆蓋父類屬性或方法的情況,導(dǎo)致子類無(wú)法訪問(wèn)父類中被覆蓋的屬性
(1) 調(diào)用未綁定的父類的方法
(2) 使用super方法(推薦)
舉例:
def __init__(self):
Fish.__init__(self) ?#調(diào)用未綁定的父類的方法,相當(dāng)于>>>Fish.__init__(Sharkfish)
self.hungry = True
運(yùn)行:
>>> shark = Sharkfish()
>>> shark.move()
我的位置是: -1 2
>>> shark.move()
我的位置是: -2 2


舉例:
def __init__(self):
super().__init__() ?#使用super方法解決
self.hungry = True
運(yùn)行:
>>> shark = Sharkfish()
>>> shark.move()
我的位置是: 8 3
>>> shark.move()
我的位置是: 7 3


多重繼承
class DerivedClassName(Base1, Base2, Base3, ...):
...
#建議少用,有可能會(huì)導(dǎo)致不可預(yù)見(jiàn)的bug(不可預(yù)見(jiàn)最麻煩)
>>> class Base1:
def fool(self):
print('我是fool,我為Base1代言...')
>>> class Base2:
def fool2(self):
print('我是fool2,我為Base2代言...')
>>> class C(Base1, Base2):
pass
>>> c = C()
>>> c.fool()
我是fool,我為Base1代言...
>>> c.fool2()
我是fool2,我為Base2代言...


組合
class Turtle:
? ? def __init__(self, x):
? ? ? ? self.num = x
class Fish:
? ? def __init__(self, x):
? ? ? ? self.num = x
class Pool:
? ? def __init__(self, x, y): ?#組合的方式嵌套class
? ? ? ? self.turtle = Turtle(x)
? ? ? ? self.fish ?= Fish(y)
? ? def print_num(self):
? ? ? ? print('水池里總共有烏龜 %d 只,小魚(yú) %d 條!' % (self.turtle.num, self.fish.num))
運(yùn)行:
>>> pool = Pool(1, 10)
>>> pool.print_num()
水池里總共有烏龜 1 只,小魚(yú) 10 條!


類、類對(duì)象、示例對(duì)象
類定義 ? ?C
類對(duì)象 ? ?C
實(shí)例對(duì)象 ?a ?b ?c
舉例:
>>> class C: ? #C, 既是類,也是類對(duì)象
count = 0
>>> a = C() ? ?#a,實(shí)例對(duì)象
>>> b = C() ? ?#b,實(shí)例對(duì)象
>>> c = C() ? ?#c,實(shí)例對(duì)象
>>> a.count
0
>>> b.count
0
>>> c.count
0
>>> c.count += 10
>>> c.count
10
>>> a.count
0
>>> b.count
0
>>> C.count ? ?#C,作為類對(duì)象
0
>>> C.count += 100 ? ?#C,作為類對(duì)象
>>> a.count
100
>>> b.count
100
>>> c.count
10


(1) 當(dāng)屬性名與方法名沖突,會(huì)導(dǎo)致方法不能正常調(diào)用。
(2) 一般遵循規(guī)則:屬性名用英文名詞,方法名用英文動(dòng)詞。
(3) python嚴(yán)格要求方法需要有實(shí)例才能被調(diào)用,即綁定的概念。


舉例:
>>> class C:
def x(self):
print('X-man!')
>>> c = C()
>>> c.x()
X-man!
>>> c.x = 1
>>> c.x
1
>>> c.x() ?#方法名字被屬性名字覆蓋,調(diào)用出錯(cuò)
TypeError: 'int' object is not callable


>>> class BB:
def printBB():
print('no zuo no die.')



>>> BB.printBB()
no zuo no die.
>>> #沒(méi)有self,也沒(méi)有將類實(shí)例化
>>> bb = BB()
>>> bb.printBB()
Traceback (most recent call last):
? File "<pyshell#187>", line 1, in <module>
? ? bb.printBB()
TypeError: printBB() takes 0 positional arguments but 1 was given
>>> class CC:
def setXY(self, x, y):
self.x = x;
self.y = y



>>> class CC:
def setXY(self, x, y):
self.x = x
self.y = y
def printXY(self):
print(self.x, self.y)



>>> dd = CC()
>>> dd.__dict__
{} ?#返回空的字典類型
>>> CC.__dict__
mappingproxy({'printXY': <function CC.printXY at 0x0000020483176EA0>, '__doc__': None, '__dict__': <attribute '__dict__' of 'CC' objects>, 'setXY': <function CC.setXY at 0x0000020483176E18>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'CC' objects>}) ?#使用類對(duì)象顯示類的屬性詳情
>>> dd.setXY(4, 5)
>>> dd.__dict__
{'y': 5, 'x': 4} ?#將實(shí)例對(duì)象dd使用類的屬性詳情實(shí)例化了
>>> # setXY(self, x, y) <==> dd.setXY(dd, x, y)
>>> del CC
>>> ee = CC()
NameError: name 'CC' is not defined
>>> dd.printXY()
4 5 ?#類中定義的屬性是靜態(tài)的,類的實(shí)例對(duì)象中也會(huì)靜態(tài)存儲(chǔ),所以實(shí)例對(duì)象dd正常存在。


類與對(duì)象的內(nèi)置函數(shù)
issubclass
功能:測(cè)試一個(gè)類是否是另外一個(gè)類的子類
issubclass(class, classinfo)
(1) 一個(gè)類被認(rèn)為是其自身的子類
(2) classinfo可以是類對(duì)象的元組,只要class屬于其中任何一個(gè)候選類的子類,則返回True
舉例:
>>> class A:
pass
>>> class B(A):
pass
>>> issubclass(B, A)
True
>>> issubclass(B, B)
True
>>> issubclass(B, object) ?#object是所有類的基類
True
>>> class C:
pass
>>> issubclass(B, C)


isinstance
功能:測(cè)試一個(gè)對(duì)象是否是一個(gè)類的實(shí)例對(duì)象
isinstance(object, classinfo)
(1) object為類的實(shí)例對(duì)象,如果不是類的實(shí)例對(duì)象,永遠(yuǎn)返回False
(2) 如果第二個(gè)參數(shù)不是類或者由類對(duì)象組成的元組,會(huì)拋出一個(gè)TypeError異常
舉例:
>>> class A:
pass
>>> class B(A):
pass
>>> class C:
pass
>>> b1 = B()
>>> isinstance(b1, B)
True
>>> isinstance(b1, A)
True
>>> isinstance(b1, C)
False
>>> isinstance(b1, (A, B, C)) ?#b1對(duì)象是否在A/B/C里面,答案是True
True


hasattr
功能:測(cè)試一個(gè)對(duì)象里面是否有指定的屬性
hasattr(object, name)
(1) object 對(duì)象名, name 是屬性名(需要用引號(hào)引起來(lái),否則報(bào)錯(cuò))


getattr
功能:返回對(duì)象指定的屬性值
getattr(object, name[, default])
(1) 如果屬性值不存在打印default,沒(méi)有default則拋出異常


setattr
功能:設(shè)置對(duì)象中指定屬性的值,如果屬性不存在則創(chuàng)建并賦值
setattr(object, name, value)


delattr
功能:刪除對(duì)象中指定的屬性,如果屬性不存在則拋出異常
delattr(object, name)


舉例:
>>> class C:
def __init__(self, x=0):
self.x = x
>>> c1 = C()
>>> hasattr(c1, 'x') ?#測(cè)試對(duì)象屬性是否存在
True
>>> hasattr(c1, x)\
NameError: name 'x' is not defined
>>> getattr(c1, 'x') ?#獲取對(duì)象屬性的值
0
>>> getattr(c1, 'y')
AttributeError: 'C' object has no attribute 'y'
>>> getattr(c1, 'y', '您所訪問(wèn)的屬性不存在!') ?#設(shè)置default默認(rèn)提示語(yǔ)
'您所訪問(wèn)的屬性不存在!'
>>> setattr(c1, 'y', 100) ?#設(shè)置對(duì)象屬性的值
>>> getattr(c1, 'y')
100
>>> delattr(c1, 'y') ?#刪除對(duì)象屬性的值
>>> delattr(c1, 'y')
Traceback (most recent call last):
? File "<pyshell#264>", line 1, in <module>
? ? delattr(c1, 'y')
AttributeError: y


property
功能:設(shè)置一個(gè)定義好的屬性,通過(guò)對(duì)象屬性來(lái)設(shè)置對(duì)象屬性
property(fget=None, fset=None, fdel=None, doc=None)
(1) fget獲取屬性的方法, fset設(shè)置屬性的方法, fdel刪除屬性的方法
舉例:
>>> class C:
def __init__(self, size=10):
self.size = size
def getSize(self):
return self.size
def setSize(self, value):
self.size = value
def delSize(self):
del self.size
x = property(getSize, setSize, delSize)
>>> c1 = C()
>>> c1.getSize()
10
>>> c1.x
10
>>> c1.x = 18
>>> c1.x
18
>>> c1.getSize()
18
>>> c1.size
18
>>> del c1.x
>>> c1.size ? ?#x與size相當(dāng)于相互引用關(guān)系,刪除其中一個(gè)另一個(gè)即不能訪問(wèn)
AttributeError: 'C' object has no attribute 'size'


20丶魔法方法 magic methods
(1) 魔法方法總是被雙下劃綫包圍,如 __init__
(2) 魔法方法是面向?qū)ο蟮膒ython的一切
(3) 魔法方法的魔力體現(xiàn)在能夠在適當(dāng)?shù)臅r(shí)候被調(diào)用


魔法方法匯總:http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403


__init__(self[, ...])
功能:初始化類對(duì)象(根據(jù)需求決定是否增加屬性參數(shù))
返回值: None
舉例:
>>> class Rectangle: #矩形類,需要長(zhǎng)和寬,所以重寫(xiě)__init__
def __init__(self, x, y):
self.x = x
self.y = y
def getPeri(self): ?#獲得周長(zhǎng)
return (self.x + self.y) * 2
def getArea(self): ?#獲得面積
return self.x * self.y
>>> rect = Rectangle(3, 4)
>>> rect.getPeri()
14
>>> rect.getArea()
12


__new__(class[, ...])
功能:創(chuàng)建一個(gè)類對(duì)象
返回值:返回一個(gè)對(duì)象
(1) 在__init__方法之前被調(diào)用,屬于類創(chuàng)建時(shí)第一個(gè)被調(diào)用的方法
舉例:
>>> class CapStr(str): ?#繼承一個(gè)不可改變的類型str
def __new__(cls, string): ?#使用new將類型的功能進(jìn)行轉(zhuǎn)換
string = string.upper()
return str.__new__(cls, string) ?#把重寫(xiě)后的str中的new方法帶傳代餐返回
>>> a = CapStr("I love M.")
>>> a
'I LOVE M.'


__del__(self)
功能:對(duì)象將要被銷毀的時(shí)候,自動(dòng)調(diào)用,屬于自動(dòng)垃圾回收方法
注意:del x != x.__del__()
舉例:
>>> class C:
def __init__(self):
print('我是init方法,我被調(diào)用了!')
def __del__(self):
print('我是del方法,我被調(diào)用了!')
>>> c1 = C()
我是init方法,我被調(diào)用了!
>>> c2 = c1 ?#對(duì)象的賦值不會(huì)調(diào)用__init__
>>> c3 = c2
>>> del c3
>>> del c2
>>> del c1 ? #其他的賦值對(duì)象del時(shí)不會(huì)調(diào)用__del__ (c2和c3只是c1的一份拷貝)
我是del方法,我被調(diào)用了!


算術(shù)運(yùn)算魔法方法
__add__(self, other) 加法:+
__sub__(self, other) 減法:-
__mul__(self, other) 乘法:*
__truediv__(self, other) 真除法:/
__floordiv__(self, other) 整數(shù)除法://
__mod__(self, other) 取模算法:%
__divmod__(self, other) divmod()調(diào)用時(shí)的行為
__pow__(self, other[, modulo]) power()調(diào)用或 ** 運(yùn)算時(shí)的行為
__lshift__(self, other) 按位左移:<<
__rshift__(self, other) 按位右移:>>
__and__(self, other) 按位與:&
__xor__(self, other) 按位異或:^
__or__(self, other) 按位或:|
舉例:
>>> class New_int(int):
def __add__(self, other):
return int.__sub__(self, other)
def __sub__(self, other):
return int.__add__(self, other)
>>> a = New_int(3)
>>> b = New_int(5)
>>> a + b
-2
>>> a - b
8
>>> class Try_int(int):
def __add__(self, other):
return int(self) + int(other)
def __sub__(self, other):
return int(self) - int(other)
>>> a = Try_int(3)
>>> b = Try_int(5)
>>> a + b
8


類定制的計(jì)時(shí)器
(1) 定制一個(gè)計(jì)時(shí)器的類
(2) start和stop方法代表啟動(dòng)計(jì)時(shí)和停止計(jì)時(shí)
(3) 假設(shè)計(jì)時(shí)器對(duì)象t1,print(t1)和直接調(diào)用t1均顯示結(jié)果
(4) 當(dāng)計(jì)時(shí)器未啟動(dòng)或已經(jīng)停止計(jì)時(shí),調(diào)用stop方法會(huì)給與溫馨的提示
(5) 兩個(gè)計(jì)時(shí)器對(duì)象可以進(jìn)行相加:t1 + t2
需要的資源:
(1) 使用time模塊的localtime方法獲取時(shí)間
(2) __str__ 方法 __repr__ 方法可用來(lái)打印文字


time 模塊
詳解鏈接:http://bbs.fishc.com/forum.php?mod=viewthread&tid=51326&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403


struct_time元組
time.struct_time(tm_year=2017, tm_mon=9, tm_mday=2, tm_hour=12, tm_min=18, tm_sec=55, tm_wday=5, tm_yday=245, tm_isdst=0)


類定制計(jì)時(shí)器代碼:http://blog.csdn.net/sinat_36184075/article/details/77806778


屬性訪問(wèn)
__getattribute__(self, name) #定義當(dāng)該類的屬性被訪問(wèn)時(shí)的行為
__getattr__(self, name) #定義當(dāng)用戶試圖獲取一個(gè)不存在的屬性時(shí)的行為
__setattr__(self, name, value) #定義當(dāng)一個(gè)屬性被設(shè)置(包括初始化)時(shí)的行為
__delattr__(self, name) #定義一個(gè)屬性被刪除時(shí)的行為
舉例:
>>> class C:
def __getattribute__(self, name):
print('getattribute')
return super().__getattribute__(name)
def __getattr__(self, name):
print('getattr')
def __setattr__(self, name, value):
print('setattr')
super().__setattr__(name, value)
def __delattr__(self, name):
print('delattr')
super().__delattr__(name)
>>> c = C()
>>> c.x
getattribute
getattr
>>> c.x = 1
setattr ?#初始化時(shí)自動(dòng)調(diào)用setattr
>>> c.x
getattribute
1
>>> del c.x
delattr


舉例:屬性訪問(wèn)時(shí)的嚴(yán)重問(wèn)題,無(wú)限遞歸
class Rectangle: ?#矩形
? ? def __init__(self, width=0, height=0): ?#寬高不相等,長(zhǎng)方形
? ? ? ? self.width = width
? ? ? ? self.height = height


? ? def __setattr__(self, name, value):
? ? ? ? if name == 'square': ?#寬高相等,正方形
? ? ? ? ? ? self.width = value
? ? ? ? ? ? self.height = value
? ? ? ? else:
? ? ? ? ? ? #self.name = value ? #會(huì)導(dǎo)致類無(wú)限遞歸自己
? ? ? ? ? ? super().__setattr__(name, value) ?#解決辦法①:super() 推薦。
? ? ? ? ? ? #self.__dict__[name] = value ? ? ?#解決辦法②:字典
? ? def getArea(self):
? ? ? ? return self.width * self.height


運(yùn)行:
>>> r1 = Rectangle(4, 5)
>>> r1.getArea()
20
>>> r1.square = 10 ?#正方形
>>> r1.width
10
>>> r1.height
10
>>> r1.getArea()
100
>>> r1.__dict__ ?#以字典的形式查看類中的屬性和值
{'width': 10, 'height': 10}


--------------------------------2017.09.03----------------------------------------
描述符 decriptor
描述符就是將某種特殊類型的類的實(shí)例指派給另一個(gè)類的屬性。
__get__(self, instance, owner) ?#用于訪問(wèn)屬性,返回屬性的值
__set__(self, instance, value) ?#將在屬性分配操作中調(diào)用,不反悔任何內(nèi)容
__delete__(self, instance) ? ?#控制刪除操作,不返回任何內(nèi)容
@self, 描述符類本身的類實(shí)例
@instance, 擁有者的類實(shí)例
@owner, 擁有者類本身
@value, 所賦的值
舉例:
>>> class MyDecriptor:
def __get__(self, instance, owner):
print('getting: ', self, instance, owner)
def __set__(self, instance, value):
print('setting: ', self, instance, value)
def __delete__(self, instance):
print('deleting: ', self, instance)
>>> class Test:
x = MyDecriptor()
>>> #MyDecriptor是x的描述符類
>>> test = Test() ? #實(shí)例化Test()類
>>> test.x
getting: ?<__main__.MyDecriptor object at 0x000002164DC31FD0> <__main__.Test object at 0x000002164DBB6F28> <class '__main__.Test'>
>>> test
<__main__.Test object at 0x000002164DBB6F28>
>>> test.x = 'X-man'
setting: ?<__main__.MyDecriptor object at 0x000002164DC31FD0> <__main__.Test object at 0x000002164DBB6F28> X-man
>>> del test.x
deleting: ?<__main__.MyDecriptor object at 0x000002164DC31FD0> <__main__.Test object at 0x000002164DBB6F28>


自定義的描述符
>>> class MyProperty:
def __init__(self, fget=None, fset=None, fdel=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
def __get__(self, instance, owner):
return self.fget(instance) ?#instance擁有者的實(shí)例對(duì)象
def __set__(self, instance, value):
self.fset(instance, value)
def __delete__(self, instance):
self.fdel(instance)



>>> class C:
def __init__(self):
self._x = None
def getX(self):
return self._x
def setX(self, value):
self._x = value
def delX(self):
del self._x
x = MyProperty(getX, setX, delX)



>>> c = C()
>>> c.x = 'X-man'
>>> c.x
'X-man' ?#使用x影響_x的值
>>> c._x
'X-man'
>>> del c.x ?#刪除后,c.x和c._x都不存在


練習(xí):溫度轉(zhuǎn)換
定義一個(gè)溫度類,然后定義兩個(gè)描述符類用于描述攝氏度和華氏度兩個(gè)屬性。
要求兩個(gè)屬性會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換,也就是說(shuō)可以給攝氏度這個(gè)屬性賦值,打印華氏度是自動(dòng)轉(zhuǎn)換后的結(jié)果。
代碼:
class Celsius:
? ? def __init__(self, value = 26.0):
? ? ? ? self.value = float(value)


? ? def __get__(self, instance, owner):
? ? ? ? return self.value
? ? def __set__(self, instance, value):
? ? ? ? self.value = float(value)


class Fahrenheit:
? ? def __get__(self, instance, owner): ?#instance就是Temperature(屬性:cel, fah)
? ? ? ? return instance.cel * 1.8 + 32
? ? def __set__(self, instance, value):
? ? ? ? #instance.cel = ('%.1f' % ((float(value) - 32) / 1.8)) ?#控制精度方法1
? ? ? ? instance.cel = round((float(value) - 32) / 1.8, 1) ? ? ?#控制精度方法2


class Temperature:
? ? cel = Celsius() ?#攝氏度
? ? fah = Fahrenheit() ?#華氏度, fah在實(shí)例對(duì)象中被賦值時(shí)調(diào)用對(duì)應(yīng)類的__set__
運(yùn)行:
>>> temp = Temperature()
>>> temp.cel
26.0
>>> temp.cel = 30
>>> temp.fah
86.0
>>> temp.fah = 100
>>> temp.cel
37.8


定制序列(容器)
(1) 如果希望定制的容器不可變,只需要定義魔法方法__len__()和__getitem__()
(2) 如果希望定制的容器可變,需要定義__len__()和__getitem__()和__setitem__()和__delitem__()


魔法方法詳解:
http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403


練習(xí):
編寫(xiě)一個(gè)不可改變的自定義列表,要求記錄列表中每個(gè)元素被訪問(wèn)的次數(shù)。
class CountList:
? ? def __init__(self, *args): ?#*args, 參數(shù)數(shù)量可變
? ? ? ? self.values = [x for x in args]
? ? ? ? self.count = {}.fromkeys(range(len(self.values)), 0)


? ? def __len__(self):
? ? ? ? return len(self.values)


? ? def __getitem__(self, key):
? ? ? ? self.count[key] += 1
? ? ? ? return self.values[key]
運(yùn)行:
>>> c1 = CountList(1, 3, 5, 7, 9)
>>> c2 = CountList(2, 4, 6, 7, 10)
>>> c1[1] ?#c1[1] == 3被訪問(wèn)1次
3
>>> c2[1]
4
>>> c1[1] + c2[1] ?#c1[1] == 3被訪問(wèn)2次
7
>>> c1.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c1[1] ?#c1[1] == 3被訪問(wèn)3次
3
>>> c1.count
{0: 0, 1: 3, 2: 0, 3: 0, 4: 0}


迭代器 iter-next
iter
iter() 內(nèi)置方法, 功能:返回一個(gè)迭代器對(duì)象
__iter__() 魔法方法


next
next() 內(nèi)置方法
__next__() ?魔法方法


for循環(huán)迭代器:
>>> links = {'百度':'http://www.baidu.com', \
'谷歌':'http://www.google.com', \
'搜狗':'http://www.sougou.com', \
'騰訊':'http://www.qq.com'}
>>> for each in links:
print("%s -> %s" % (each, links[each]))
谷歌 -> http://www.google.com
搜狗 -> http://www.sougou.com
騰訊 -> http://www.qq.com
百度 -> http://www.baidu.com


iter迭代器:
>>> string = 'yuan.jiang'
>>> it = iter(string)
>>> while True:
try:
each = next(it)
except StopIteration:
break;
print(each, end=' ')
運(yùn)行:
y u a n . j i a n g?


斐波那契數(shù)列迭代器
>>> class Fibs: ?#斐波那契數(shù)列
def __init__(self, n=10): ? ?#加一個(gè)參數(shù)n控制迭代范圍
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self ?#本身就是一個(gè)迭代器
def __next__(self):
self.a, self.b = self.b, self.a+self.b
if self.a > self.n:
raise StopIteration
return self.a
>>> fibs = Fibs()
>>> for each in fibs:
print(each, end=' ')
1 1 2 3 5 8
>>> fibs = Fibs(100)
>>> for each in fibs:
print(each, end=' ')
1 1 2 3 5 8 13 21 34 55 89


生成器 yield
(1) 生成器是一種特殊的迭代器,兼容next()內(nèi)置方法
(2) 生成器模仿了協(xié)同程序
協(xié)同程序:可以運(yùn)行的對(duì)立函數(shù)調(diào)用,函數(shù)可以暫停或掛起,并再需要的時(shí)候從程序離開(kāi)的地方繼續(xù)活著重新開(kāi)始。
舉例:
>>> def MyGen():
print('生成器被執(zhí)行!')
yield 1
yield 2
>>> myg = MyGen()
>>> next(myg)
生成器被執(zhí)行!
1
>>> next(myg)
2
>>> next(myg)
StopIteration
>>> for i in MyGen(): ?#for循環(huán)自動(dòng)檢測(cè)迭代器的StopIteration異常
print(i)
生成器被執(zhí)行!
1
2
>>> def fibs():
a = 0
b = 1
while True:
a, b = b, a+b
yield a
>>> for each in fibs():
if each > 100:
break
print(each, end=' ')
1 1 2 3 5 8 13 21 34 55 89?


列表推導(dǎo)式
>>> a = [i for i in range(100) if not (i % 2) and (i % 3)] ?#列表推導(dǎo)式
>>> a
[2, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, 56, 58, 62, 64, 68, 70, 74, 76, 80, 82, 86, 88, 92, 94, 98]
>>> b = {i:i % 2 == 0 for i in range(10)} ?#字典推導(dǎo)式(例子:小于10以內(nèi)的偶數(shù))
>>> b
{0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False}
>>> c = {i for i in [1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 3, 2, 1]} ?#集合推導(dǎo)式(元素不重復(fù))
>>> c
{1, 2, 3, 4, 5, 6, 7, 8}
#沒(méi)有字符串推導(dǎo)式,引號(hào)內(nèi)的強(qiáng)制解釋為字符串
>>> e = (i for i in range(10)) ?#沒(méi)有元組推導(dǎo)式,()小括號(hào)生成的是生成器推導(dǎo)式
>>> e
<generator object <genexpr> at 0x00000261E200A7D8>
>>> next(e)
0
>>> next(e)
1
>>> for each in e:
print(each, end=' ')
2 3 4 5 6 7 8 9?
>>> sum(i for i in range(100) if i % 2)
2500


生成器擴(kuò)展閱讀:
http://bbs.fishc.com/forum.php?mod=viewthread&tid=56023&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403


21丶模塊 module
容器 -> 數(shù)據(jù)的封裝
函數(shù) -> 語(yǔ)句的封裝
類 ? -> 方法和屬性的封裝
模塊 -> 程序的封裝,其實(shí)就是.py的python程序
(1) import導(dǎo)入的.py模塊文件必須放在與python.exe同一目錄下,即可正確導(dǎo)入。
(2) 導(dǎo)入方法有三種:
① import 模塊名
② from 模塊名 import 函數(shù)名1, 函數(shù)名2, ... ?#不建議這樣用,可能會(huì)覆蓋系統(tǒng)函數(shù)
③ import 模塊名 as 新名字
舉例:
在python下新建test_module文件夾:C:\python\test_module
C:\python\test_module\TempeatureConversion.py
C:\python\test_module\calc.py
#TempeatureConversion.py
def c2f(cel):
? ? fah = cel * 1.8 + 32
? ? return fah


def f2c(fah):
? ? cel = round((fah - 32) / 1.8, 1)
? ? return cel


#calc.py
import TemperatureConversion as tc


print('32攝氏度 = %.1f華氏度' % tc.c2f(32))
print('99華氏度 = %.1f攝氏度' % tc.f2c(99))


運(yùn)行calc.py:
=================== RESTART: C:\python\test_module\calc.py ===================
32攝氏度 = 89.6華氏度
99華氏度 = 37.2攝氏度
>>>?


__name__
if __name__ = '__main__': ?#決定是.py文件中的代碼是當(dāng)前程序運(yùn)行,還是導(dǎo)入到其他程序中作為模塊使用而運(yùn)行
作用:限制為自身.py程序運(yùn)行才執(zhí)行的代碼區(qū)域


搜索路徑 path
(1) 最佳存放模塊的目錄:C:\\python\\lib\\site-packages
>>> import sys
>>> sys.path
['', 'C:\\python\\Lib\\idlelib', 'C:\\python\\python35.zip', 'C:\\python\\DLLs', 'C:\\python\\lib', 'C:\\python', 'C:\\python\\lib\\site-packages']
>>> sys.path.append('C:\\python\\test_module') ?#自定義的模塊目錄可以append進(jìn)去
>>> sys.path
['', 'C:\\python\\Lib\\idlelib', 'C:\\python\\python35.zip', 'C:\\python\\DLLs', 'C:\\python\\lib', 'C:\\python', 'C:\\python\\lib\\site-packages', 'C:\\python\\test_module']
>>> import TemperatureConversion as temp
>>> temp.c2f(32)
89.6


包 package
(1) python目錄下創(chuàng)建一個(gè)文件夾,用于存放相關(guān)的模塊,文件夾的名字即包(package)的名字
(2) 在文件夾中創(chuàng)建一個(gè) __init__.py 的模塊文件,內(nèi)容可以為空
舉例:
C:\python\test_module\calc.py
C:\python\test_module\M1\TemperatureConversion.py ?#M1文件夾名,即為包名
C:\python\test_module\M1\__init__.py ?#告訴python運(yùn)行時(shí)將其解釋為包
#calc.py中修改為:包名.模塊名
import M1.TemperatureConversion as tc
print('32攝氏度 = %.1f華氏度' % tc.c2f(32))
print('99華氏度 = %.1f攝氏度' % tc.f2c(99))


自帶電池:python標(biāo)準(zhǔn)庫(kù)
(1) 電池:python-IDLE 幫助文檔 F1
(2) 來(lái)自全球開(kāi)發(fā)者貢獻(xiàn)的python模塊:https://pypi.python.org/pypi
#也可以自己寫(xiě)模塊發(fā)布上去。
(3) PEP:python增強(qiáng)建議書(shū),規(guī)范與定義python各種加強(qiáng)和延伸功能的技術(shù)規(guī)格,即參考標(biāo)準(zhǔn)
(4) PEP規(guī)范內(nèi)容歷史:http://www.python.org/dev/peps
(5) IDLE中模塊信息查看:
>>> import timeit
>>> print(timeit.__doc__) ?#幫助文檔
>>> dir(timeit) ?#內(nèi)置方法
>>> timeit.__all__ ?#__all__屬性是可供外界調(diào)用的類或接口函數(shù)
>>> timeit.__file__ ?#__file__屬性是顯示模塊源代碼在本地的位置(學(xué)習(xí)高手的代碼)
>>> help(timeit) ?#幫助文檔


timeit 模塊詳解
地址:http://bbs.fishc.com/thread-55593-1-1.html


22丶python實(shí)例:網(wǎng)絡(luò)爬蟲(chóng)
python訪問(wèn)網(wǎng)絡(luò): urllib (是個(gè)包模塊)
URL一般格式:
protocol://hostname[:port]/path/[;parameters][?query]#fragment
URL三部分組成:
(1) 協(xié)議:http, https, ftp, file, ed2k...
(2) 域名/IP地址:如http默認(rèn)端口號(hào)80
(3) 資源具體地址:如目錄或文件名


查看幫助文檔后發(fā)現(xiàn)urllib包有4個(gè)模塊:
urllib.request #for opening and reading URLs?
urllib.error #containing the exceptions raised by urllib.request?
urllib.parse #for parsing URLs?
urllib.robotparser #for parsing robots.txt files?
嘗鮮:
>>> import urllib.request
>>> response = urllib.request.urlopen('http://www.fishc.com')
>>> html = response.read()
>>> print(html)
b'\xef...\r\n</html>\r\n' ?#整個(gè)網(wǎng)頁(yè)的二進(jìn)制文件以16進(jìn)制顯示
>>> html = html.decode('utf-8') ?#按其編碼方式解碼
>>> print(html)
"""
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
</body>
</html>
"""


訪問(wèn)網(wǎng)頁(yè)內(nèi)容存儲(chǔ)本地
舉例:
import urllib.request as url_req


response = url_req.urlopen('http://placekitten.com/g/1920/1080')
cat_img = response.read()


with open('cat_1920_1080.jpg', 'wb') as f:
? ? f.write(cat_img)
運(yùn)行:
會(huì)生成這個(gè)文件:C:\Users\Jan\Desktop\python_study\cat_1920_1080.jpg


實(shí)現(xiàn)POST請(qǐng)求 - 自動(dòng)翻譯機(jī)
import urllib.request as url_req
import urllib.parse ? as url_prs
import json ?#json, 輕量級(jí)的數(shù)據(jù)交換格式


while True:
? ? content = input('請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:')
? ? if content == '.q':
? ? ? ? break
? ? else:
? ? ? ? #注意url地址<有道翻譯>,按小甲魚(yú)視頻中的可能不對(duì),需到網(wǎng)上查別人的
? ? ? ? url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http://www.youdao.com/'
? ? ? ? data = {} ? #字典類型


? ? ? ? data['type'] = 'AUTO'
? ? ? ? data['i'] = content
? ? ? ? data['doctype'] = 'json'
? ? ? ? data['xmlVersion'] = '1.8'
? ? ? ? data['keyfrom'] = 'fanyi.web'
? ? ? ? data['ue'] = 'UTF-8'
? ? ? ? data['action'] = 'FY_BY_CLICKBUTTON'
? ? ? ? data['typoResult'] = 'true'


? ? ? ? data = url_prs.urlencode(data).encode('utf-8')
? ? ? ? response = url_req.urlopen(url, data)
? ? ? ? html = response.read().decode('utf-8')
? ? ? ? target = json.loads(html)
? ? ? ? print('翻譯結(jié)果:%s' % (target['translateResult'][0][0]['tgt']))
#缺陷:能夠被識(shí)別為代碼訪問(wèn),而非瀏覽器,即非人類訪問(wèn)
運(yùn)行:
========= RESTART: C:\Users\Jan\Desktop\python_study\translation.py =========
請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:生存,還是毀滅,這是一個(gè)問(wèn)題
翻譯結(jié)果:To survive, or not to be, this is a problem
請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:To be or not to be, it's a question.
翻譯結(jié)果:生存還是毀滅,這是一個(gè)問(wèn)題。
請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:.q
>>>?


修改header
(1) 通過(guò)Request的headers參數(shù)修改,字典形式
(2) 通過(guò)Request.add_header()方法修改
追加header模擬瀏覽器訪問(wèn):
import urllib.request as url_req
import urllib.parse ? as url_prs
import json ?#json, 輕量級(jí)的數(shù)據(jù)交換格式


while True:
? ? content = input('請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:')
? ? if content == '.q':
? ? ? ? break
? ? else:
? ? ? ? #注意url地址,視頻中的可能不對(duì)需到網(wǎng)上查
? ? ? ? url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http://www.youdao.com/'


? ? ? ? #header方法1:創(chuàng)建字典,請(qǐng)求中傳參
? ? ? ? '''
? ? ? ? head = {} ?#模擬瀏覽器訪問(wèn) Request Headers
? ? ? ? head['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
? ? ? ? '''
? ? ? ? data = {} ?#From data
? ? ? ? data['type'] = 'AUTO'
? ? ? ? data['i'] = content
? ? ? ? data['doctype'] = 'json'
? ? ? ? data['xmlVersion'] = '1.8'
? ? ? ? data['keyfrom'] = 'fanyi.web'
? ? ? ? data['ue'] = 'UTF-8'
? ? ? ? data['action'] = 'FY_BY_CLICKBUTTON'
? ? ? ? data['typoResult'] = 'true'
? ? ? ? data = url_prs.urlencode(data).encode('utf-8')


? ? ? ? '''req = url_req.Request(url, data, head) ?#調(diào)用請(qǐng)求的方法:data, head '''
? ? ? ? #header方法2:請(qǐng)求中追加header
? ? ? ? req = url_req.Request(url, data)
? ? ? ? req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')


? ? ? ? response = url_req.urlopen(req)
? ? ? ? html = response.read().decode('utf-8')
? ? ? ? target = json.loads(html)
? ? ? ? print('翻譯結(jié)果:%s' % (target['translateResult'][0][0]['tgt']))
運(yùn)行:
========= RESTART: C:\Users\Jan\Desktop\python_study\translation.py =========
請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:生存,還是毀滅,這是一個(gè)問(wèn)題
翻譯結(jié)果:To survive, or not to be, this is a problem
請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:To be or not to be, it's a question.
翻譯結(jié)果:生存還是毀滅,這是一個(gè)問(wèn)題。
請(qǐng)輸入需要翻譯的內(nèi)容<.q退出>:.q
>>>?


代理
作用:讓爬蟲(chóng)偽裝瀏覽器請(qǐng)求,讓http服務(wù)器不會(huì)認(rèn)為是非人類訪問(wèn)。
步驟:
(1) 參數(shù)是一個(gè)字典{'類型':'代理ip:端口號(hào)'}
proxy_support = urllib.request.ProxyHandler({})
(2) 定制、創(chuàng)建一個(gè)opener
opener = urllib.request.build_opener(proxy_support)
(3) 安裝opener
urllib.request.install_opener(opener)
(4) 調(diào)用opener
opener.open(url)
#或:urllib.request.urlopen(url)
代碼:
import urllib.request as url_req
import random


url = 'http://www.whatismyip.com.tw' ?#這個(gè)網(wǎng)站訪問(wèn)它會(huì)顯示自己的ip地址


#待完善:抓取代理ip網(wǎng)站上的ip和端口,存入iplist
iplist = ['115.197.136.78:8118', '118.250.50.69:80', '183.133.81.57:8118', ?'113.77.240.236:9797', '139.129.166.68:3128'] ?#使用random隨機(jī)取ip


#網(wǎng)上查的免費(fèi)代理ip網(wǎng)站:http://www.xicidaili.com/
proxy_support = url_req.ProxyHandler({'http':random.choice(iplist)})
opener = url_req.build_opener(proxy_support)


#headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
opener.addheaders = [('User-Agent', 'Chrome/55.0.2883.87')]
url_req.install_opener(opener)


#req = url_req.Request(url, headers=headers)
#response = url_req.urlopen(req)
response = url_req.urlopen(url)


html = response.read().decode('utf-8')
print(html)


補(bǔ)充:
Beautiful Soup 是用Python寫(xiě)的一個(gè)HTML/XML的解析器,使用安裝python-IDLE時(shí)附帶的pip命令,直接在windows下執(zhí)行:
C:\python> pip install bs4
#一鍵安裝搞定,python中測(cè)試能否導(dǎo)入成功
>>> from bs4 import BeautifulSoup
>>> #成功導(dǎo)入,失敗會(huì)報(bào)異常。


采集代理ip
import urllib.request as url_req
from bs4 import BeautifulSoup ?#此庫(kù)需要安裝:win-cmd執(zhí)行"pip install bs4"即可
import random
import pprint as ppr


#這個(gè)網(wǎng)站訪問(wèn)它會(huì)顯示自己的ip地址
display_ip_url = 'http://www.whatismyip.com.tw' ? #'http://ip.chinaz.com/getip.aspx'


#代理ip網(wǎng)站, http協(xié)議類型
proxy_ip_url = 'http://www.xicidaili.com/wt/'


header = {}
header['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'


def getProxyIp(): ?#獲取代理ip
? ? proxyip_list = []
? ? for i in range(1, 2):
? ? ? ? try:
? ? ? ? ? ? url = proxy_ip_url + str(i) ?#抓取前2頁(yè)
? ? ? ? ? ? req = url_req.Request(url, headers=header)
? ? ? ? ? ? res = url_req.urlopen(req).read()
? ? ? ? ? ? soup = BeautifulSoup(res, "html.parser") ?#BeautifulSoup(markup, “html.parser”) html解析器
? ? ? ? ? ? ips = soup.findAll('tr') ?#findAll()搜索解析器解析出來(lái)的html文檔樹(shù)
? ? ? ? ? ? for x in range(1, len(ips)):
? ? ? ? ? ? ? ? ip = ips[x]
? ? ? ? ? ? ? ? tds = ip.findAll('td') ?#ip和端口都在tr標(biāo)簽中的td標(biāo)簽中
? ? ? ? ? ? ? ? ip_tmp = tds[1].contents[0] + ':' + tds[2].contents[0]
? ? ? ? ? ? ? ? proxyip_list.append(ip_tmp) ?#追加到列表
? ? ? ? except:
? ? ? ? ? ? continue
? ? return proxyip_list


iplist = getProxyIp()
#print(iplist) ? #for test
ppr.pprint(iplist) ?#以更規(guī)范的格式顯示輸出結(jié)果


#第一步:ProxyHandler傳參
ip_port = random.choice(iplist)
proxy_support = url_req.ProxyHandler({'http':ip_port}) ?#從列表中隨機(jī)選擇代理ip和端口項(xiàng)
print('ip:port ? ?' + ip_port)
#第二步:opener創(chuàng)建
opener = url_req.build_opener(proxy_support)
#第三步:opener安裝
opener.addheaders = [('User-Agent', 'Chrome/55.0.2883.87')]
url_req.install_opener(opener)
#第四步:opener調(diào)用
#response = url_req.urlopen(display_ip_url)
response = opener.open(display_ip_url) ?


html = response.read().decode('utf-8')
print(html)


運(yùn)行:
======== RESTART: C:\Users\Jan\Desktop\python_study\proxy_support.py ========
<!DOCTYPE HTML>
<html>
? <head>
? ...
? </head>
? <body>
? <h1>IP位址</h1>
? <span data-ip='183.56.177.130'><b style='font-size: 1.5em;'>183.56.177.130</b> ?</span>
? <span data-ip-country='CN'><i>CN</i></span>
? <h1>真實(shí)IP</h1>
? <span data-ip-real='113.110.143.94'><b style='font-size: 1.5em;'>113.110.143.94</b></span>
? <span data-ip-real-country='CN'><i>CN</i></span>
? <script type="application/json" id="ip-json">
{
"ip": "183.56.177.130",
"ip-country": "CN",
"ip-real": "113.110.143.94",
"ip-real-country": "CN"
}
? </script>
? ...
? </body>
</html>


--------------------------------2017.09.04----------------------------------------
urllib.request 返回響應(yīng)后的內(nèi)置方法
import urllib.request as url_req
req = url_req.Request('http://url')
res = url_req.urlopen(req) #打開(kāi)一個(gè)鏈接,參數(shù)可以是一個(gè)字符串或者Request對(duì)象
res.geturl() #返回鏈接的字符串,即urlopen的字符串參數(shù)
res.info() #返回http響應(yīng)數(shù)據(jù)包的頭headers, 輸出:print(res.info())
res.getcode() #返回http響應(yīng)的狀態(tài)碼


舉例:
=============== RESTART: C:/Users/Jan/Desktop/download_cat.py ===============
>>> res.geturl()
'http://placekitten.com/g/500/600'
>>> res.info()
<http.client.HTTPMessage object at 0x0000022E09C006D8>
>>> res.headers
<http.client.HTTPMessage object at 0x0000022E09C006D8>
>>> print(res.info())
Date: Mon, 04 Sep 2017 13:11:21 GMT
Content-Type: image/jpeg
Content-Length: 26590
Connection: close
Set-Cookie: __cfduid=d8354310653b8846db674de048175187b1504530681; expires=Tue, 04-Sep-18 13:11:21 GMT; path=/; domain=.placekitten.com; HttpOnly
Accept-Ranges: bytes
X-Powered-By: PleskLin
Access-Control-Allow-Origin: *
Cache-Control: public
Expires: Thu, 31 Dec 2020 20:00:00 GMT
Server: cloudflare-nginx
CF-RAY: 399131b5435b6d4e-SJC
>>> res.getcode()
200


python爬蟲(chóng)下載妹子圖
代碼:#代理ip不太穩(wěn)定,免費(fèi)代理很多時(shí)好時(shí)壞
import urllib.request
import os
import random
import pprint as ppr
from bs4 import BeautifulSoup


header = {}
header_key = 'User-Agent'
header_value = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
header[header_key] = header_value


def get_proxy_ip(): ?#獲取代理ip
? ? proxyip_list = []
? ? proxy_ip_url = 'http://www.xicidaili.com/wt/'
? ? for i in range(1, 2):
? ? ? ? try:
? ? ? ? ? ? url = proxy_ip_url + str(i)
? ? ? ? ? ? req = urllib.request.Request(url, headers=header)
? ? ? ? ? ? res = urllib.request.urlopen(req).read()
? ? ? ? ? ? soup = BeautifulSoup(res, "html.parser")
? ? ? ? ? ? ips = soup.findAll('tr')
? ? ? ? ? ? for x in range(1, len(ips)):
? ? ? ? ? ? ? ? ip = ips[x]
? ? ? ? ? ? ? ? tds = ip.findAll('td')
? ? ? ? ? ? ? ? ip_tmp = tds[1].contents[0] + ':' + tds[2].contents[0]
? ? ? ? ? ? ? ? proxyip_list.append(ip_tmp)
? ? ? ? except:
? ? ? ? ? ? continue
? ? return proxyip_list


#打開(kāi)url接口函數(shù)
def url_open(url):
? ? req = urllib.request.Request(url)
? ? req.add_header(header_key, header_value)
? ? '''
? ? #使用代理模擬真人訪問(wèn)而不是代碼訪問(wèn)
? ? iplist = get_proxy_ip()
? ? #ppr.pprint(iplist) ?#for test
? ? ip_port = random.choice(iplist)
? ? proxy_support = urllib.request.ProxyHandler({'http':ip_port})
? ? print('ip:port ? ?' + ip_port) ?#for test
? ? opener = urllib.request.build_opener(proxy_support)
? ? opener.addheaders = [('User-Agent', 'Chrome/55.0.2883.87')]
? ? urllib.request.install_opener(opener)
? ? '''
? ? res = urllib.request.urlopen(url)
? ? html = res.read()


? ? print(url)
? ? return html


def get_page(url):
? ? html = url_open(url).decode('utf-8')


? ? a = html.find('current-comment-page') + 23
? ? b = html.find(']', a) ?#從a位置開(kāi)始找到一個(gè)]符號(hào)
? ? print (html[a:b]) ?#for test


? ? return html[a:b]


def find_imgs(url):
? ? html = url_open(url).decode('utf-8')
? ? img_addrs = []


? ? a = html.find('img src=') ?#找到 img src= 的位置


? ? while a != -1:
? ? ? ? b = html.find('.jpg', a, a+255) ? #找到從a位置開(kāi)始,以 .jpg 結(jié)尾的地方
? ? ? ? if b != -1: ?#find找不到時(shí)返回-1
? ? ? ? ? ? img_addrs.append('http:' + html[a+9:b+4]) ?#圖片鏈接地址追加到列表中, 9=len('img src="'), 4=len('.jpg')
? ? ? ? else:
? ? ? ? ? ? b = a + 9
? ? ? ??
? ? ? ? a = html.find('img src=', b) ? ? ?#下一次循環(huán)所找的位置就是從b開(kāi)始


? ? #for each in img_addrs:
? ? # ? ?print(each)


? ? return img_addrs


def save_imgs(folder, img_addrs):
? ? for each in img_addrs:
? ? ? ? filename = each.split('/')[-1] ?#split以/分割字符串,-1取最后一個(gè)元素
? ? ? ? with open(filename, 'wb') as f:
? ? ? ? ? ? img = url_open(each)
? ? ? ? ? ? f.write(img)


def download_mm(folder='mm_dir', pages=25):
? ? if os.path.exists(folder):
? ? ? ? os.chdir(folder)
? ? else:
? ? ? ? os.mkdir(folder)
? ? ? ? os.chdir(folder)


? ? url = 'http://jandan.net/ooxx/' ?#實(shí)際圖源來(lái)源于新浪服務(wù)器
? ? page_num = int(get_page(url)) ? ?#函數(shù)get_page()


? ? for i in range(pages):
? ? ? ? page_num -= i
? ? ? ? page_url = url + 'page-' + str(page_num) + '#comments'
? ? ? ? img_addrs = find_imgs(page_url) ?#函數(shù)find_imgs()
? ? ? ? save_imgs(folder, img_addrs)


if __name__ == '__main__':
? ? download_mm()


--------------------------------2017.09.05----------------------------------------
正則表達(dá)式
"我知道,可以使用正則表達(dá)式解決現(xiàn)在遇到的難題。"于是,現(xiàn)在他就有兩個(gè)問(wèn)題了。
>>> import re
>>> re.search(r'Hello', 'I love you, Hello!~') ?#search()方法用于在字符串中搜索正則表達(dá)式模式第一次出現(xiàn)的位置
<_sre.SRE_Match object; span=(12, 17), match='Hello'> ?#第12-16個(gè)字符位置
>>> re.search(r'lo', 'hello')
<_sre.SRE_Match object; span=(3, 5), match='lo'>
>>> 'hello'.find('lo')
3
#.點(diǎn)號(hào):匹配除了換行符的任何字符
>>> re.search(r'.', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(0, 1), match='I'>
#匹配點(diǎn)號(hào)本身,使用\反斜杠轉(zhuǎn)義即可
>>> re.search(r'\.', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(17, 18), match='.'>
#\d表示匹配一個(gè)0~9的數(shù)字
>>> re.search(r'\d', 'I love 123, baidu.com!~')
<_sre.SRE_Match object; span=(7, 8), match='1'>
>>> re.search(r'\d\d\d', 'I love 123, baidu.com!~')
<_sre.SRE_Match object; span=(7, 10), match='123'>
>>> re.search(r'\d\d\d.\d\d\d.\d\d\d.\d\d\d', '192.168.111.123:8080')
<_sre.SRE_Match object; span=(0, 15), match='192.168.111.123'>
>>> re.search(r'\d\d\d.\d\d\d.\d\d\d.\d\d\d', '192.168.1.1') #無(wú)法匹配,位數(shù)不同
#使用[]創(chuàng)建一個(gè)字符類
>>> re.search(r'[aeiou]', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(3, 4), match='o'>
>>> re.search(r'[aeiouAEIOU]', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(0, 1), match='I'>
#-短杠:表示匹配的范圍
>>> re.search(r'[a-z]', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(2, 3), match='l'>
>>> re.search(r'[0-9]', 'I love 123, baidu.com!~')
<_sre.SRE_Match object; span=(7, 8), match='1'>
#{}大括號(hào):來(lái)限定匹配的次數(shù)
>>> re.search(r'ab{3}c', 'zabbbcz')
<_sre.SRE_Match object; span=(1, 6), match='abbbc'>
#{}3,10代表3到10次重復(fù)次數(shù),不能有空格出現(xiàn)
>>> re.search(r'ab{3, 10}c', 'zabbbbbcz')
>>> re.search(r'ab{3,10}c', 'zabbbbbcz')
<_sre.SRE_Match object; span=(1, 8), match='abbbbbc'>
>>> re.search(r'[0-2][0-5][0-5]', '188') ?#錯(cuò)誤示范
>>> re.search(r'[0-255]', '188') ?#0,1,2,5其中任何一個(gè),匹配
<_sre.SRE_Match object; span=(0, 1), match='1'>
>>> re.search(r'[01]\d\d|2[0-4]\d|25[0-5]', '188') ?#0-255正則表達(dá)式
<_sre.SRE_Match object; span=(0, 3), match='188'>
#ip地址正則表達(dá)式
>>> re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])', '192.168.1.1')
<_sre.SRE_Match object; span=(0, 11), match='192.168.1.1'>
>>> re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])', '255.255.255.0')
<_sre.SRE_Match object; span=(0, 13), match='255.255.255.0'>
#此ip表達(dá)式的一點(diǎn)bug:
>>> re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])', '11192.168.41.8888')
<_sre.SRE_Match object; span=(2, 15), match='192.168.41.88'>


#ip地址匹配的正則表達(dá)式【嚴(yán)謹(jǐn)版】
import re
ptnIP = re.compile(r'(?<![\d.])' # 前導(dǎo) 無(wú) 數(shù)字和小數(shù)點(diǎn)
? ? ? ? ? ? ? ? ? ?r'(?:(?:'
? ? ? ? ? ? ? ? ? ?r'[01]?\d?\d' # ? 0 ~ 199
? ? ? ? ? ? ? ? ? ?r'|2[0-4]\d' ?# 200 ~ 249
? ? ? ? ? ? ? ? ? ?r'|25[0-5])' ?# 250 ~ 255
? ? ? ? ? ? ? ? ? ?r'\.){3}' ? ? # 3組 xxx.
? ? ? ? ? ? ? ? ? ?r'(?:'
? ? ? ? ? ? ? ? ? ?r'[01]?\d?\d'
? ? ? ? ? ? ? ? ? ?r'|2[0-4]\d'
? ? ? ? ? ? ? ? ? ?r'|25[0-5])'
? ? ? ? ? ? ? ? ? ?r'(?![\d.])' ?# 后續(xù) 無(wú) 數(shù)字和小數(shù)點(diǎn)
? ? ? ? ? ? ? ? ? )
test_IP = (
? ? ? ? '0.0.0.0'
? ? ? ? ';1.22.333.444' ? ? ? ? #不合法
? ? ? ? ';2.0.0.256' ? ? ? ? ? ?#不合法
? ? ? ? ';3.22.33.23333333' ? ? #不合法
? ? ? ? ';4.2.3.4.5' ? ? ? ? ? ?#不合法
? ? ? ? ';5.111.222.99'
? ? ? ? ';6.0.0.0'
? ? ? ? ';7.234.234.234'
? ? ? ? ';255.255.255.255'
? ? ? ? ';234.234.234.234'
? ? ? ? ';1192.168.41.888' ? ? ?#不合法
? ? ? ? )
match = ptnIP.findall(test_IP)
print(match)


運(yùn)行:
========== RESTART: C:\Users\Jan\Desktop\python_study\ip_regular.py ==========
['0.0.0.0', '5.111.222.99', '6.0.0.0', '7.234.234.234', '255.255.255.255', '234.234.234.234'] ?#輸出均為合法ip


--------------------------------2017.09.07----------------------------------------
Python3 正則表達(dá)式特殊符號(hào)及用法(詳細(xì)列表)
http://blog.csdn.net/riba2534/article/details/54288552


正則表達(dá)式舉例:
import urllib.request
import re


header = {}
header_key = 'User-Agent'
header_value = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
header[header_key] = header_value


def open_url(url):
? ? req = urllib.request.Request(url)
? ? req.add_header(header_key, header_value)
? ? page = urllib.request.urlopen(req)
? ? html = page.read().decode('utf-8')


? ? return html


def get_img(html):
? ? p = r'<img class="BDE_Image" src="([^"]+\.jpg)' ?# 正則表達(dá)式匹配貼吧圖片鏈接
? ? imglist = re.findall(p, html) ?# findall中的p包含子組()的話,會(huì)單獨(dú)返回子組


? ? # test start
? ? for each in imglist:
? ? ? ? print(each)
? ? # test end


? ? for each in imglist:
? ? ? ? filename = each.split("/")[-1]
? ? ? ? urllib.request.urlretrieve(each, filename, None)


if __name__ == '__main__':
? ? url = 'https://tieba.baidu.com/p/5310571187' ?# 下載百度貼吧圖片示例
? ? get_img(open_url(url))


運(yùn)行:
https://imgsa.baidu.com/forum/w%3D580/sign=0b340d2849a7d933bfa8e47b9d4ad194/f1f8e3dde71190ef7241a5e3c51b9d16fcfa60a4.jpg
https://imgsa.baidu.com/forum/w%3D580/sign=6ff2514ff0f2b211e42e8546fa816511/fe4fbf014a90f6030c47ab7b3212b31bb151ed60.jpg
https://imgsa.baidu.com/forum/w%3D580/sign=7f8aadd5f9d3572c66e29cd4ba136352/b9dc748b4710b912bda70cc2c8fdfc03934522f1.jpg


優(yōu)化采集代理ip:
import urllib.request
import re


header = {}
header_key = 'User-Agent'
header_value = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
header[header_key] = header_value


def open_url(url):
? ? req = urllib.request.Request(url)
? ? req.add_header(header_key, header_value)
? ? page = urllib.request.urlopen(req)
? ? html = page.read().decode('utf-8')


? ? return html


def get_ip(html):
? ? ptnIP = (r'(?<![\d.])' # 前導(dǎo) 無(wú) 數(shù)字和小數(shù)點(diǎn)
? ? ? ? ? ? ?r'(?:(?:'
? ? ? ? ? ? ?r'[01]?\d?\d' # ? 0 ~ 199
? ? ? ? ? ? ?r'|2[0-4]\d' ?# 200 ~ 249
? ? ? ? ? ? ?r'|25[0-5])' ?# 250 ~ 255
? ? ? ? ? ? ?r'\.){3}' ? ? # 3組 xxx.
? ? ? ? ? ? ?r'(?:'
? ? ? ? ? ? ?r'[01]?\d?\d'
? ? ? ? ? ? ?r'|2[0-4]\d'
? ? ? ? ? ? ?r'|25[0-5])'
? ? ? ? ? ? ?r'(?![\d.])') # 后續(xù) 無(wú) 數(shù)字和小數(shù)點(diǎn)
? ? iplist = re.findall(ptnIP, html) ?# findall中的p包含子組()的話,會(huì)單獨(dú)返回子組


? ? # test start
? ? for each in iplist:
? ? ? ? print(each)
? ? # test end


if __name__ == '__main__':
? ? url = 'http://www.xicidaili.com/wt/' ?# 下載代理ip
? ? get_ip(open_url(url))


異常處理
URLError 舉例:
>>> import urllib.request
>>> import urllib.error
>>> req = urllib.request.Request('http://www.ooxx-hello.com') ?#打開(kāi)一個(gè)不存在的鏈接
>>> try:
urllib.request.urlopen(req)
except urllib.error.URLError as e:
print(e.reason)
[Errno 11001] getaddrinfo failed ?#錯(cuò)誤信息


HTTPError 舉例:
>>> import urllib.request
>>> import urllib.error
>>> req = urllib.request.Request('http://www.fishC.com/ooxx.html')
>>> try:
urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
print(e.code)
print(e.read())
404
b'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p>The requested URL /ooxx.html was not found on this server.</p>\n<hr>\n<address>Apache Server at www.fishc.com Port 80</address>\n</body></html>\n'


處理異常的寫(xiě)法:
from urllib.request import Request, urlopen
from urllib.error import URLError
req = Request('http://someurl/')
try:
response = urlopen(req)
except URLError as e:
if hasattr(e, 'reason'):
print('We failed to reach a server.')
print('Reason: ', e.reason)
elif hasattr(e, 'code'):
print('The server couldn\'t fulfill the request.')
print('Error code: ', e.code)
else:
#everything is fine.


--------------------------------2017.09.08----------------------------------------
Scrapy爬蟲(chóng)框架


① Scrapy的安裝與環(huán)境搭建
Scrapy對(duì)應(yīng)python2.7的版本。(安裝過(guò)程中如遇任何問(wèn)題均可百度搜索一下,這是程序員必須學(xué)會(huì)的快速解決問(wèn)題的辦法)
1. 安裝python2.7(32位版本)
安裝包:python-2.7.6-win32.msi
設(shè)置環(huán)境變量:win-運(yùn)行-cmd
> C:\Python27\python.exe C:\Python27\tools\Scripts\win_add2path.py
重啟windows系統(tǒng),驗(yàn)證安裝是否成功:
> python --version
#如果顯示是3.多的版本,請(qǐng)參考python2/3版本切換任性切換設(shè)置:http://blog.csdn.net/sinat_36184075/article/details/77872708
2. 安裝pywin32(32位版本)
安裝包:pywin32-215.win32-py2.7.exe
3. 安裝python2.7的pip程序
安裝程序:get-pip.py
安裝方法:win-cmd> python C:\python\Scrapy\get-pip.py
先把pip的路徑添加到windows的環(huán)境變量中。
重啟windows系統(tǒng),驗(yàn)證安裝是否成功:
> pip --version
#如果沒(méi)有顯示版本信息,請(qǐng)參考pip2/3任性切換設(shè)置:http://blog.csdn.net/sinat_36184075/article/details/77872708
4. 安裝lxml
安裝環(huán)境包:VCForPython27.msi
> pip2 install lxml
#如果pip2的路徑有添加到windows中的話,安裝可以成功。如果不成功,使用下面安裝包安裝
安裝包:lxml-3.2.3.win32-py2.7.exe
5. 安裝OpenSSL
> pip2 install pyOpenSSL
#如果pip2的路徑有添加到windows中的話,安裝可以成功。如果不成功,使用下面安裝包安裝
安裝包:egenix-pyopenssl-0.13.7.win32-py2.7.msi
6. 安裝Scrapy
> pip2 install service_identity
> pip2 install Scrapy
驗(yàn)證是否安裝成功:
> Scrapy
#如果提示找不到命令的話,可能需要一個(gè)工具環(huán)境支持:Twisted-15.0.0.win32-py2.7.msi
安裝完Twisted后再次嘗試驗(yàn)證即可。




② Scrapy框架爬蟲(chóng)程序初探
一個(gè)為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫(xiě)的應(yīng)用框架。最初是為了頁(yè)面抓取所設(shè)計(jì)的,也可以應(yīng)用在獲取API所訪問(wèn)的數(shù)據(jù)上,或者說(shuō)通用的網(wǎng)絡(luò)爬蟲(chóng)上。
使用Scrapy抓取一個(gè)網(wǎng)站一共需要四個(gè)步驟:
1. 創(chuàng)建一個(gè)Scrapy項(xiàng)目;
2. 定義Item容器;
3. 編寫(xiě)爬蟲(chóng);
4. 存儲(chǔ)內(nèi)容。


---Scrapy框架(官網(wǎng))圖示---


實(shí)驗(yàn)網(wǎng)站對(duì)象:www.dmoz.org


1. 創(chuàng)建一個(gè)Scrapy項(xiàng)目:crawler
C:\Users\Jan\Desktop\python_study>Scrapy startproject crawler
#crawler是我們的項(xiàng)目名稱
在\python_study\crawler\文件夾中即是我們的爬蟲(chóng)框架。


Item是保存爬取到的數(shù)據(jù)的容器,其使用方法和python字典類似,并且提供了額外保護(hù)機(jī)制來(lái)避免拼寫(xiě)錯(cuò)誤導(dǎo)致的未定義字段錯(cuò)誤。


2. 定義Item容器:
#crawler\crawler\items.py
import scrapy
class CrawlerItem(scrapy.Item):
? ? # define the fields for your item here like:
? ? # name = scrapy.Field()
? ? title = scrapy.Field()
? ? link = scrapy.Field()
? ? desc = scrapy.Field()


3. 編寫(xiě)爬蟲(chóng):
編寫(xiě)爬蟲(chóng)類Spider,Spider是用戶編寫(xiě)用于從網(wǎng)站上爬取數(shù)據(jù)的類。其包含了一個(gè)用于下載的初始化URL,然后是如何跟進(jìn)網(wǎng)頁(yè)中的鏈接以及如何分析頁(yè)面中的內(nèi)容,還有提取生成item的方法。
#crawler\crawler\spiders\crawler_spider.py 新建文件
import scrapy


class CrawlerSpider(scrapy.Spider):
? ? name = 'csdn' ?#爬蟲(chóng)名字,調(diào)用的時(shí)候使用
? ? allowed_domains = ['csdn.net']
? ? start_urls = ['http://geek.csdn.net/AI']


? ? def parse(self, response):
? ? ? ? filename = response.url.split('/')[-2]
? ? ? ? with open(filename, 'wb') as f:
? ? ? ? ? ? f.write(response.body)
3.1 爬
win-cmd:
C:\Users\Jan\Desktop\python_study>cd crawler
C:\Users\Jan\Desktop\python_study\crawler>scrapy crawl csdn ?#csdn爬蟲(chóng)類中的name
2017-09-08 21:56:28 [scrapy.utils.log] INFO: Scrapy 1.4.0 started (bot: crawler)
...
2017-09-08 21:56:30 [scrapy.core.engine] INFO: Spider opened
2017-09-08 21:56:30 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-09-08 21:56:30 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-09-08 21:56:30 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://geek.csdn.net/robots.txt> (referer: None) ?#Here: robots.txt
2017-09-08 21:56:30 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://geek.csdn.net/AI> (referer: None) ?#Here: 我們的目標(biāo)爬取鏈接
2017-09-08 21:56:31 [scrapy.core.engine] INFO: Closing spider (finished)
...
2017-09-08 21:56:31 [scrapy.core.engine] INFO: Spider closed (finished)


#爬取的內(nèi)容存儲(chǔ)位置(爬取網(wǎng)站的源碼文件):
C:\Users\Jan\Desktop\python_study\crawler\ 目錄下 geek.csdn.net 的NET文件。


3.2 取
在Scrapy中使用的是一種基于XPath和CSS的表達(dá)式機(jī)制:Scrapy Selectors(選擇器)
Selector是一個(gè)選擇器,有4個(gè)基本方法:
xpath() 傳入xpath表達(dá)式,返回該表達(dá)式所對(duì)應(yīng)的所有節(jié)點(diǎn)的selector list列表。
css() 傳入CSS表達(dá)式,返回該表達(dá)式所對(duì)應(yīng)的所有節(jié)點(diǎn)的selector list列表。
extract() 序列化該節(jié)點(diǎn)為unicode字符串并返回list。
re() 根據(jù)傳入的正則表達(dá)式對(duì)數(shù)據(jù)進(jìn)行提取,返回unicode字符串list列表。


win-cmd進(jìn)入項(xiàng)目根目錄后執(zhí)行:scrapy shell "http://target_url/"
C:\Users\Jan\Desktop\python_study\crawler>scrapy shell "http://geek.csdn.net/AI"
2017-09-08 22:05:48 [scrapy.utils.log] INFO: Scrapy 1.4.0 started (bot: crawler)
...
2017-09-08 22:05:50 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-09-08 22:05:50 [scrapy.core.engine] INFO: Spider opened
2017-09-08 22:05:50 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://geek.csdn.net/robots.txt> (referer: None)
2017-09-08 22:05:50 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://geek.csdn.net/AI> (referer: None)
...
>>> response.body #輸出網(wǎng)頁(yè)的源碼信息
>>> response.headers ?#輸出網(wǎng)頁(yè)的頭部信息
{'Date': ['Fri, 08 Sep 2017 14:06:31 GMT'], 'Content-Type': ['text/html; charset=utf-8'], 'Server': ['openresty'], 'Vary': ['Accept-Encoding', 'Accept-Encoding']}


XPath是一門(mén)在網(wǎng)頁(yè)中查找特定信息的語(yǔ)言,所以用XPath來(lái)篩選數(shù)據(jù),要比使用正則表達(dá)式容易些。
/html/head/title 選擇HTML文檔中<head>標(biāo)簽內(nèi)的<title>元素
/html/head/title/text() 選擇上面提到的<title>元素的文字
//td 選擇所有的<td>元素
//div[@class="mine"] 選擇所有具有 class="mine" 屬性的div元素


response.xpath() = response.selector.xpath() ?#已經(jīng)映射。可以直接使用.xpath()
>>> response.xpath('//title')
[<Selector xpath='//title' data=u'<title>CSDN\u6781\u5ba2\u5934\u6761-\u63a8\u8350\u6bcf\u65e5\u6700\u65b0\u6700\u70edIT\u8d44\u8baf</title>'>] ?#\u的那些是中文字符,編碼方式?jīng)Q定顯示
>>> response.xpath('//title/text()').extract() ?#截圖title內(nèi)容
[u'CSDN\u6781\u5ba2\u5934\u6761-\u63a8\u8350\u6bcf\u65e5\u6700\u65b0\u6700\u70edIT\u8d44\u8baf']
>>> sel.xpath('//span/a') ?#輸出所有<span><a>標(biāo)簽的內(nèi)容全部輸出
2017-09-08 22:36:08 [py.warnings] WARNING: <string>:1: ScrapyDeprecationWarning: "sel" shortcut is deprecated. Use "response.xpath()", "response.css()" or "response.selector" instead
>>> sel.xpath('//span/a/text()').extract() ?#獲取所有<span><a>標(biāo)簽中的字符串,即標(biāo)題
>>> sel.xpath('//span/a/@href').extract() ?#獲取<span><a>中的連接地址
>>> sites = sel.xpath('//div/div/div/dl/dd/span/a/text()').extract() ?#按照標(biāo)簽包裹的層級(jí)<body>下開(kāi)始找到包裹標(biāo)題的<a>標(biāo)簽寫(xiě)入xpath中
>>> for title in sites: ?#使用for循環(huán)打印可以自動(dòng)將Unicode轉(zhuǎn)換為對(duì)應(yīng)中文編碼顯示
... ? ? print(title)
自己動(dòng)手做聊天機(jī)器人 四十二-(重量級(jí)長(zhǎng)文)從理論到實(shí)踐開(kāi)發(fā)自己的聊天機(jī)器人
微軟攜手 Facebook 推出開(kāi)源項(xiàng)目 打造共享神經(jīng)網(wǎng)絡(luò)模型
Taylor Swift vs 人工智能:作詞誰(shuí)更強(qiáng)?
推薦13個(gè)機(jī)器學(xué)習(xí)框架
...
>>> sites = sel.xpath('//div/div/div[@class="directory-url"]/dl/dd/span/a/text()').extract()
#其中[@class="directory-url"]的功能是:過(guò)濾掉對(duì)應(yīng)樣式類的內(nèi)容,此處僅做演示


#crawler\crawler\spiders\crawler_spider.py 修改代碼
import scrapy


class CrawlerSpider(scrapy.Spider):
? ? name = 'csdn'
? ? allowed_domains = ['csdn.net']
? ? start_urls = ['http://geek.csdn.net/AI']


? ? def parse(self, response):
? ? ? ? sel = scrapy.selector.Selector(response)
? ? ? ? sites = sel.xpath('//div/div/div/dl/dd/span')
? ? ? ? for site in sites:
? ? ? ? ? ? title = site.xpath('a/text()').extract()
? ? ? ? ? ? link ?= site.xpath('a/@href').extract()
? ? ? ? ? ? desc ?= site.xpath('text()').extract()
? ? ? ? ? ? print(title, link, desc)
win-cmd:
C:\Users\Jan\Desktop\python_study\crawler>scrapy crawl csdn
#運(yùn)行就可以將print中的內(nèi)容在爬取時(shí)一并顯示出來(lái)(輸出內(nèi)容略)


4. 存儲(chǔ)內(nèi)容
最常見(jiàn)的導(dǎo)出為json格式。
中文亂碼問(wèn)題:http://bbs.fishc.com/thread-85672-1-1.html
#crawler\crawler\spiders\crawler_spider.py ?構(gòu)造items的列表對(duì)象
import scrapy
from crawler.items import CrawlerItem


class CrawlerSpider(scrapy.Spider):
? ? name = 'csdn'
? ? allowed_domains = ['csdn.net']
? ? start_urls = ['http://geek.csdn.net/AI']


? ? def parse(self, response):
? ? ? ? sel = scrapy.selector.Selector(response)
? ? ? ? items = []
? ? ? ? sites = sel.xpath('//div/div/div/dl/dd/span')
? ? ? ? for site in sites:
? ? ? ? ? ? item = CrawlerItem() ?#實(shí)例化一個(gè)item類(類似于字典)
? ? ? ? ? ? item['title'] = site.xpath('a/text()').extract()
? ? ? ? ? ? item['link'] ?= site.xpath('a/@href').extract()
? ? ? ? ? ? item['desc'] ?= site.xpath('text()').extract()
? ? ? ? ? ? print(item['title'], item['link'], item['desc'])
? ? ? ? ? ? items.append(item)


? ? ? ? return items


#crawler\crawler\pipelines.py ?設(shè)置抓取內(nèi)容存儲(chǔ)的文件名以及校正中文亂碼
import json
import codecs


store_filename = 'items.json' ? ?#item.json指的是要保存的json格式文件的名稱


class CrawlerPipeline(object):
? ? def __init__(self):
? ? ? ? self.file = codecs.open(store_filename, 'wb', encoding='utf-8') ?#中文編碼格式一般都是'utf-8'
? ? def process_item(self, item, spider):
? ? ? ? line = json.dumps(dict(item), ensure_ascii=False) + '\n' ?#這一句會(huì)將你每次返回的字典抓取出來(lái),“ensure_ascii=False”這一句話很重要,如果是True的話就是我們保存的\u4e2d\u56fd這種格式了
? ? ? ? self.file.write(line) ?#寫(xiě)入到文件中
? ? ? ? return item


#crawler\crawler\setting.py ?使pipelines.py生效,取消注釋ITEM_PIPELINES
ITEM_PIPELINES = {
? ? 'crawler.pipelines.CrawlerPipeline': 300, ?#300是正常值,不變。
}


win-cmd運(yùn)行scrapy,即可自動(dòng)在\crawler\目錄下生成items.json文件,并且中文顯示正常:
C:\Users\Jan\Desktop\python_study\crawler>scrapy crawl csdn
C:\Users\Jan\Desktop\python_study\crawler\items.json ?#中文正常。
{"title": ["自己動(dòng)手做聊天機(jī)器人 四十二-(重量級(jí)長(zhǎng)文)從理論到實(shí)踐開(kāi)發(fā)自己的聊天機(jī)器人"], "link": ["http://www.shareditor.com/blogshow?blogId=136&hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
{"title": ["微軟攜手 Facebook 推出開(kāi)源項(xiàng)目 打造共享神經(jīng)網(wǎng)絡(luò)模型"], "link": ["http://tech.163.com/17/0908/08/CTQ1403R00097U80.html"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
{"title": ["Taylor Swift vs 人工智能:作詞誰(shuí)更強(qiáng)?"], "link": ["http://dataquestion.com/taylor-vs-ai"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
...


--------------------------------2017.09.09----------------------------------------
23丶GUI界面的終極選擇 Tkinter
Tkinter是python的默認(rèn)GUI模塊庫(kù)。
示例1:主窗口及標(biāo)題
import tkinter as tk


app = tk.Tk() ?#根窗口的實(shí)例(root窗口)
app.title('Tkinter root window') ?#根窗口標(biāo)題


theLabel = tk.Label(app, text='我的第2個(gè)窗口程序!') ?#label組件及文字內(nèi)容
theLabel.pack() ?#pack()用于自動(dòng)調(diào)節(jié)組件的尺寸


app.mainloop() ?#窗口的主事件循環(huán),必須的。


示例2:按鈕
import tkinter as tk


class APP:
? ? def __init__(self, master): ?#root 傳參賦值給master
? ? ? ? frame = tk.Frame(master) ?#frame 組件
? ? ? ? frame.pack(side=tk.LEFT, padx=10, pady=10)


? ? ? ? self.hi_there = tk.Button(frame, text='打招呼', bg='black', fg='white', command=self.say_hi) ?#Button按鈕, command中調(diào)用定義的方法
? ? ? ? self.hi_there.pack()


? ? def say_hi(self):
? ? ? ? print('臥槽,居然打了個(gè)招呼!~')


root = tk.Tk()
app = APP(root)


root.mainloop()


示例3:圖片
from tkinter import *


root = Tk()
textLabel = Label(root,
? ? ? ? ? ? ? ? ? text='請(qǐng)重試!\n您的操作不被允許!', ?#文字支持換行
? ? ? ? ? ? ? ? ? justify=LEFT, ?#左對(duì)齊
? ? ? ? ? ? ? ? ? padx=10, ?#左邊距10px
? ? ? ? ? ? ? ? ? pady=10) ?#右邊距10px?
textLabel.pack(side=LEFT)


#顯示圖片
photo = PhotoImage(file='tk_image.png')
imageLabel = Label(root, image=photo)
imageLabel.pack(side=RIGHT)


mainloop()


示例4:背景
from tkinter import *


root = Tk()


photo = PhotoImage(file='tk4_bg.png')
theLabel = Label(root,
? ? ? ? ? ? ? ? ?text='生存還是毀滅\n這是一個(gè)問(wèn)題',
? ? ? ? ? ? ? ? ?justify=LEFT,
? ? ? ? ? ? ? ? ?image=photo,
? ? ? ? ? ? ? ? ?compound=CENTER,
? ? ? ? ? ? ? ? ?font=('華文隸書(shū)', 20),
? ? ? ? ? ? ? ? ?fg='blue')
theLabel.pack()


mainloop()


示例5:按鈕交互
from tkinter import *


def callback():
? ? var.set('吹吧你,我才不信呢!')


root = Tk()


frame1 = Frame(root)
frame2 = Frame(root)


var = StringVar()
var.set('請(qǐng)重試!\n您的操作不被允許!')
textLabel = Label(frame1,
? ? ? ? ? ? ? ? ? textvariable=var,
? ? ? ? ? ? ? ? ? justify=LEFT) ?#左對(duì)齊
textLabel.pack(side=LEFT)


#顯示圖片
photo = PhotoImage(file='tk_image.png')
imageLabel = Label(root, image=photo)
imageLabel.pack(side=RIGHT)


theButton = Button(frame2, text='我是超級(jí)管理員', command=callback)
theButton.pack()


frame1.pack(padx=10, pady=10)
frame2.pack(padx=10, pady=10)


mainloop()


示例6:選項(xiàng)按鈕
from tkinter import *


root = Tk()


v = IntVar()


c = Checkbutton(root, text='測(cè)試一下', variable=v) ?#v用來(lái)存放選中狀態(tài)
c.pack()


l = Label(root, textvariable=v)
l.pack() ?#未選中顯示為0,選中顯示1


mainloop()


示例7:多個(gè)方框選項(xiàng)
from tkinter import *


root = Tk()


GIRLS = ['西施', '貂蟬', '王昭君', '楊玉環(huán)']


v = ?[]
for girl in GIRLS:
? ? v.append(IntVar())
? ? b = Checkbutton(root, text=girl, variable=v[-1])
? ? b.pack(anchor=W) ?#設(shè)置對(duì)齊方位,東E南S西W北N


mainloop()


示例8:多個(gè)圓點(diǎn)選項(xiàng) Radiobutton
from tkinter import *


root = Tk()


v = IntVar()


Radiobutton(root, text='one', variable=v, value=1).pack(anchor=W)
Radiobutton(root, text='two', variable=v, value=2).pack(anchor=W)
Radiobutton(root, text='three', variable=v, value=3).pack(anchor=W)
Radiobutton(root, text='four', variable=v, value=4).pack(anchor=W)


mainloop()


示例9:內(nèi)陷填充按鈕選項(xiàng) Radiobutton indicatoron
from tkinter import *


root = Tk()


LANGS = [
? ? ('C', 1),
? ? ('C++', 2),
? ? ('shell', 3),
? ? ('python', 4)]


v = IntVar()
v.set(1)


for lang, num in LANGS: ?#對(duì)應(yīng)列表中包含元組同時(shí)執(zhí)行多個(gè)循環(huán)
? ? b = Radiobutton(root, text=lang, variable=v, value=num, indicatoron=False)
? ? b.pack(fill=X)


mainloop()


示例10:附帶標(biāo)題的圓點(diǎn)選項(xiàng) LabelFrame
from tkinter import *


root = Tk()


group = LabelFrame(root, text='最好的開(kāi)發(fā)語(yǔ)言是?', padx=5, pady=5)
group.pack(padx=10, pady=10)


LANGS = [
? ? ('C', 1),
? ? ('C++', 2),
? ? ('shell', 3),
? ? ('python', 4)]


v = IntVar()
v.set(1)


for lang, num in LANGS: ?#對(duì)應(yīng)列表中包含元組同時(shí)執(zhí)行多個(gè)循環(huán)
? ? b = Radiobutton(group, text=lang, variable=v, value=num)
? ? b.pack(anchor=W)


mainloop()


示例11:輸入框 Entry
from tkinter import *


root = Tk()


e = Entry(root)
e.pack(padx=20, pady=20)


e.delete(0, END)
e.insert(0, '默認(rèn)文本...')


mainloop()


示例12:按鈕和輸入框交互
from tkinter import *


root = Tk()
root.title('輸入框與按鈕程序')


Label(root, text='作品:').grid(row=0, column=0)
Label(root, text='作者:').grid(row=1, column=0)


e1 = Entry(root)
e2 = Entry(root)
e1.grid(row=0, column=1, padx=10, pady=5)
e2.grid(row=1, column=1, padx=10, pady=5)


def show(): ?#當(dāng)輸入內(nèi)容時(shí)點(diǎn)擊獲取信息會(huì)打印
? ? print('作品:《%s》' % e1.get())
? ? print('作者:《%s》' % e2.get())


Button(root, text='獲取信息', width=10, command=show) \
? ? ? ? ? ? ?.grid(row=3, column=0, sticky=W, padx=10, pady=5)
Button(root, text='點(diǎn)擊退出', width=10, command=root.quit) \
? ? ? ? ? ? ?.grid(row=3, column=1, sticky=E, padx=10, pady=5)
#退出按鈕必須是雙擊打開(kāi).py文件才可以,而不是在IDLE下調(diào)試運(yùn)行時(shí)


mainloop()


示例12:登陸框程序
from tkinter import *


root = Tk()
root.title('登陸程序')


Label(root, text='賬號(hào):').grid(row=0, column=0)
Label(root, text='密碼:').grid(row=1, column=0)


v1 = StringVar()
v2 = StringVar()


e1 = Entry(root, textvariable=v1)
e2 = Entry(root, textvariable=v2, show='*')
e1.grid(row=0, column=1, padx=10, pady=5)
e2.grid(row=1, column=1, padx=10, pady=5)


def show():
? ? print('賬號(hào):%s' % e1.get())
? ? print('密碼:%s' % e2.get())


Button(root, text='芝麻開(kāi)門(mén)', width=10, command=show) \
? ? ? ? ? ? ?.grid(row=3, column=0, sticky=W, padx=10, pady=5)
Button(root, text='點(diǎn)擊退出', width=10, command=root.quit) \
? ? ? ? ? ? ?.grid(row=3, column=1, sticky=E, padx=10, pady=5)
#退出按鈕必須是雙擊打開(kāi).py文件才可以,而不是在IDLE下調(diào)試運(yùn)行時(shí)


mainloop()


示例13:輸入對(duì)錯(cuò)驗(yàn)證程序
from tkinter import *


root = Tk()
root.title('輸入對(duì)錯(cuò)驗(yàn)證')


def test():
? ? if e1.get() == '張三':
? ? ? ? print('正確!')
? ? ? ? return True
? ? else:
? ? ? ? print('錯(cuò)誤!')
? ? ? ? e1.delete(0, END)
? ? ? ? return False


v = StringVar()


#focusout指定在當(dāng)前輸入框失去焦點(diǎn)時(shí),代表輸入完,會(huì)去調(diào)用test校驗(yàn)<tab>鍵可測(cè)試
e1 = Entry(root, textvariable=v, validate='focusout', validatecommand=test)
e2 = Entry(root)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)


mainloop()


示例13:簡(jiǎn)單計(jì)算器程序
from tkinter import *


root = Tk()
root.title('計(jì)算器程序')


frame = Frame(root)
frame.pack(padx=10, pady=10)


v1 = StringVar()
v2 = StringVar()
v3 = StringVar()


def test(content):
? ? return content.isdigit()


testCMD = frame.register(test)
#focusout指定在當(dāng)前輸入框失去焦點(diǎn)時(shí),代表輸入完,會(huì)去調(diào)用test校驗(yàn)<tab>鍵可測(cè)試
e1 = Entry(frame, width=10, textvariable=v1, validate='key', \
? ? ? ? ? ?validatecommand=(testCMD, '%P')).grid(row=0, column=0) ?#width的單位是字符數(shù)
Label(frame, text='+').grid(row=0, column=1)


e2 = Entry(frame, width=10, textvariable=v2, validate='key', \
? ? ? ? ? ?validatecommand=(testCMD, '%P')).grid(row=0, column=2)
Label(frame, text='=').grid(row=0, column=3)


e3 = Entry(frame, width=10, textvariable=v3, state='readonly').grid(row=0, column=4)


def calc():
? ? result = int(v1.get()) + int(v2.get())
? ? v3.set(str(result))


Button(frame, text='計(jì)算結(jié)果', command=calc).grid(row=1, column=2, pady=5)


mainloop()


示例14:按鈕刪除列表中的選項(xiàng)
from tkinter import *


master= Tk()


theLB = Listbox(master, selectmode=SINGLE, height=15) ?#SINGLE單選,MULTIPLE多選,height設(shè)置顯示項(xiàng)數(shù)
theLB.pack()


for item in ['筆', '墨', '紙', '硯']:
? ? theLB.insert(END, item) ?#END表示最后一個(gè)


for item in range(11):
? ? theLB.insert(END, item)
? ??


theButton = Button(master, text='刪除', \
? ? ? ? ? ? ? ? ? ?command=lambda x=theLB:x.delete(ACTIVE) ) #ACTIVE表示當(dāng)前選中的值
theButton.pack()


mainloop()


示例15:為列表組件添加滾動(dòng)條
安裝垂直滾動(dòng)條步驟:
1) 設(shè)置該組件的yscrollbarcommand選項(xiàng)為Scrollbar組件的set方法;
2) 設(shè)置Scrollbar組件的command選項(xiàng)為該組件的yview()方法。
from tkinter import *


root = Tk()
root.title('滾動(dòng)條程序')


sb = Scrollbar(root)
sb.pack(side=RIGHT, fill=Y)


lb = Listbox(root, yscrollcommand=sb.set)


for i in range(1000):
? ? lb.insert(END, i)
lb.pack(side=LEFT, fill=BOTH)


#讓滾動(dòng)條與選項(xiàng)互通互連
sb.config(command=lb.yview)


mainloop()


示例16:滑塊滾動(dòng)條 Scale
from tkinter import *


root = Tk()
root.title('滑塊程序')


s1 = Scale(root, from_=0, to=100, tickinterval=5, resolution=5, length=200) ?#默認(rèn)是垂直, tickinterval精度刻度, length單位是像素
s1.pack()


s2 = Scale(root, from_=0, to=100, tickinterval=5, orient=HORIZONTAL, length=400)
s2.pack()


def show():
? ? print(s1.get(), s2.get())


#獲取滑塊的當(dāng)前位置,點(diǎn)擊后才有效
Button(root, text='音量:', command=show).pack()


mainloop()


示例17:文本組件 Text ?(插入按鈕)
from tkinter import *


root = Tk()
root.title('Text')


text = Text(root, width=30, height=20)
text.pack()


#窗口中的文本可編輯
text.insert(INSERT, '這里是顯示的文本信息內(nèi)容。\n') ?#INSERT表示輸入光標(biāo)插入的位置
text.insert(END, '對(duì)比一下效果。')


def show():
? ? print('提交中...') ?#此行內(nèi)容顯示在IDLE中


#插入一個(gè)Button組件
b1 = Button(text, text='提交', command=show)
text.window_create(INSERT, window=b1) ?#將b1插入


mainloop()


示例18:文本組件 Text ?(插入圖片)
from tkinter import *


root = Tk()
root.title('Text')


text = Text(root, width=100, height=30)
text.pack()


photo = PhotoImage(file="tk_image.png")
def show_img():
? ? text.image_create(END, image=photo)


#插入一個(gè)圖片
b1 = Button(text, text='插入圖片', command=show_img)
text.window_create(INSERT, window=b1) ?#將b1插入


mainloop()


示例19:文本組件 Text ?(Indexes:索引定位)
from tkinter import *


root = Tk()
root.title('Text')


text = Text(root, width=30, height=10)
text.pack()
text.insert(INSERT, 'I love baidu.com!')


text.tag_add('tag1', '1.7', '1.12', '1.14') ?#1.7~1.12 baidu ? 1.14 o
text.tag_add('tag2', '1.7', '1.12', '1.14')
text.tag_config('tag1', background='blue', foreground='yellow')
text.tag_config('tag2', foreground='red') ?#文字會(huì)以red為準(zhǔn)


mainloop()


示例20:文本組件中可點(diǎn)擊連接
from tkinter import *
import webbrowser as wb


root = Tk()
root.title('GUI link show')


text = Text(root, width=30, height=5)
text.pack()


text.insert(INSERT, 'I love baidu.com!')
text.tag_add('link', '1.7', '1.16')
text.tag_config('link', foreground='blue', underline=True)


def show_arrow_cursor(event):
? ? text.config(cursor='arrow')


def show_xterm_cursor(event):
? ? text.config(cursor='xterm')


def click(event):
? ? wb.open('http://www.baidu.com')


#綁定事件
text.tag_bind('link', '<Enter>', show_arrow_cursor) ?#<Enter>鼠標(biāo)進(jìn)入
text.tag_bind('link', '<Leave>', show_xterm_cursor) ?#<Enter>鼠標(biāo)離開(kāi)
text.tag_bind('link', '<Button-1>', click) ?#<Enter>鼠標(biāo)點(diǎn)擊


mainloop()


示例21:文本組件之MD5
from tkinter import *
import hashlib ?#用于獲取文件的MD5值,檢查內(nèi)容是否有修改


root = Tk()
root.title('link click')


text = Text(root, width=50, height=10)
text.pack()


text.insert(INSERT, 'I love www.baidu.com')
contents = text.get('1.0', END)


def getSig(contents):
? ? m = hashlib.md5(contents.encode())
? ? return m.digest()


sig = getSig(contents)


def check():
? ? contents = text.get('1.0', END)
? ? if sig != getSig(contents):
? ? ? ? print('內(nèi)容有修改,是否保存?')
? ? else:
? ? ? ? print('無(wú)任何修改!')


Button(root, text='檢查', command=check).pack()


mainloop()


示例22:文本組件之全文搜索
from tkinter import *


root = Tk()
root.title('link click')


text = Text(root, width=50, height=10)
text.pack()


text.insert(INSERT, 'I love www.baidu.com')


def getIndex(text, index):
? ? return tuple(map(int, str.split(text.index(index), '.')))


start = '1.0' ?#開(kāi)頭的位置,第1行的第0個(gè)下標(biāo)位置
while True:
? ? pos = text.search('o', start, stopindex=END) ?#查找文本中字符o的位置
? ? if not pos:
? ? ? ? break
? ? print('找到啦,位置是:', getIndex(text, pos))
? ? start = pos + '+1c' ?#'+1c'指向下一個(gè)字符


mainloop()


示例23:文本組件之撤銷操作
from tkinter import *


root = Tk()
root.title('link click')


text = Text(root, width=50, height=10, undo=True) ?#undo模式開(kāi)啟
text.pack()


text.insert(INSERT, 'I love www.baidu.com')


def show():
? ? text.edit_undo()


Button(root, text='撤銷', command=show).pack() ?#多次撤銷會(huì)刪除文本組件內(nèi)的內(nèi)容


mainloop()


示例24:繪制組件 Canvas
from tkinter import *


root = Tk()
root.title('Canvas')


w = Canvas(root, width=500, height=300) ?#background='black' 改變背景色
w.pack()


#黃色的矩形
w.create_rectangle(50, 50, 450, 250, fill='yellow') ?#參數(shù):左邊距, 上邊距, 寬, 高
#紅色的橫線
w.create_line(0, 300//2, 500, 300//2, fill='red')
#藍(lán)色的豎虛線
w.create_line(500//2, 0, 500//2, 300, fill='blue', dash=(4, 4)) ?#dash 虛線


mainloop()


示例25:繪制組件 Canvas (修改和刪除圖形)
from tkinter import *


root = Tk()
root.title('Canvas')


w = Canvas(root, width=500, height=300) ?#background='black' 改變背景色
w.pack()


rect1 = w.create_rectangle(50, 50, 450, 250, fill='yellow') ?#參數(shù):左邊距, 上邊距, 寬, 高
line1 = w.create_line(0, 300//2, 500, 300//2, fill='red')
line2 = w.create_line(500//2, 0, 500//2, 300, fill='blue', dash=(4, 4)) ?#dash 虛線


w.coords(line1, 0, 25, 500, 25) ?#移動(dòng)位置
w.itemconfig(rect1, fill='red')
w.delete(line2)


Button(root, text='刪除全部', command=(lambda x=ALL:w.delete(x))).pack()


mainloop()


示例26:繪制組件 Canvas (圖形正中心)
from tkinter import *


root = Tk()
root.title('Canvas')


w = Canvas(root, width=600, height=300)
w.pack()




line1 = w.create_line(0, 0, 600, 300, fill='green', width=3)
line1 = w.create_line(600, 0, 0, 300, fill='green', width=3)
rect1 = w.create_rectangle(60, 30, 540, 270, fill='green')
rect2 = w.create_rectangle(120, 60, 480, 240, fill='yellow')


w.create_text(300, 150, text='Hello, python!')


mainloop()


示例27:繪制組件 Canvas (橢圓和圓形)
from tkinter import *


root = Tk()
root.title('Canvas')


w = Canvas(root, width=600, height=300)
w.pack()


w.create_rectangle(60, 30, 540, 270, dash=(4, 4))
w.create_oval(60, 30, 540, 270, fill='pink') ?#橢圓是通過(guò)限定矩形的方式畫(huà)出來(lái),圓形通過(guò)正方形
#w.create_oval(60, 30, 300, 270, fill='pink') ?#正方形對(duì)應(yīng)正圓(60-300=30-270)
w.create_text(300, 150, text='wow~')


mainloop()


示例28:繪制組件 Canvas (五角星)
from tkinter import *
import math as m ?#用到sin和cos數(shù)學(xué)函數(shù)


root = Tk()
root.title('Canvas')


w = Canvas(root, width=600, height=300, background='red')
w.pack()


center_x = 300
center_y = 150
r = 150


points = [
? ? #左上點(diǎn)
? ? center_x - int(r * m.sin(2 * m.pi / 5)),
? ? center_y - int(r * m.cos(2 * m.pi / 5)),
? ? #右上點(diǎn)
? ? center_x + int(r * m.sin(2 * m.pi / 5)),
? ? center_y - int(r * m.cos(2 * m.pi / 5)),
? ? #左下點(diǎn)
? ? center_x - int(r * m.sin(m.pi / 5)),
? ? center_y + int(r * m.cos(m.pi / 5)),
? ? #頂點(diǎn)
? ? center_x,
? ? center_y - r,
? ? #右下點(diǎn)
? ? center_x + int(r * m.sin(m.pi / 5)),
? ? center_y + int(r * m.cos(m.pi / 5)),
? ? ]


w.create_polygon(points, outline='yellow', fill='yellow') ?#polygon多邊形


mainloop()


示例29:繪制組件 Canvas (自定義畫(huà)板)
#繪制一個(gè)極小的圓來(lái)代表一個(gè)點(diǎn)(tkinter本身不支持畫(huà)點(diǎn))
from tkinter import *


root = Tk()
root.title('Canvas draw tool')


w = Canvas(root, width=400, height=200, background='white')
w.pack()


def paint(event):
? ? x1, y1 = (event.x - 1), (event.y - 1)
? ? x2, y2 = (event.x + 1), (event.y + 1)
? ? w.create_oval(x1, y1, x2, y2, fill='red')


w.bind('<B1-Motion>', paint) ?#<B1-Motion>綁定鼠標(biāo)左鍵事件


Label(root, text='按住鼠標(biāo)左鍵并移動(dòng),開(kāi)始繪制吧!~~').pack(side=BOTTOM)


mainloop()


示例30:菜單組件 Menu (主菜單/下拉菜單/右鍵菜單/單多選菜單/按鈕菜單/選項(xiàng)菜單(列表))
from tkinter import *


root = Tk()
root.title('Main Menu Show')


def callback():
? ? print('你好~')


menubar = Menu(root)


#注冊(cè)菜單:文件(下拉菜單)
filemenu = Menu(menubar, tearoff=False) ?#來(lái)自主菜單,tearoff參數(shù)可讓菜單窗口分離
filemenu.add_command(label='新建', command=callback)
filemenu.add_command(label='打開(kāi)...', command=callback)
filemenu.add_separator() ?#分割線
filemenu.add_command(label='保存', command=callback)
filemenu.add_separator() ?#分割線
filemenu.add_command(label='退出', command=root.quit)
menubar.add_cascade(label='文件(W)', menu=filemenu)


#主菜單:編輯(下拉菜單)
editmenu = Menu(menubar, tearoff=False) ?#來(lái)自主菜單
editmenu.add_command(label='撤銷', command=callback)
editmenu.add_command(label='重做', command=callback)
editmenu.add_separator() ?#分割線
editmenu.add_command(label='剪切', command=callback)
editmenu.add_command(label='復(fù)制', command=callback)
editmenu.add_command(label='粘貼', command=callback)
editmenu.add_separator() ?#分割線
editmenu.add_command(label='全選', command=callback)
editmenu.add_separator() ?#分割線
editmenu.add_command(label='查找...', command=callback)
menubar.add_cascade(label='編輯(B)', menu=editmenu)


#主菜單:多選√ checkbutton(下拉菜單)
openVar = IntVar()
saveVar = IntVar()
quitVar = IntVar()
optionmenu = Menu(menubar, tearoff=False)
optionmenu.add_checkbutton(label='多選項(xiàng)1', command=callback, variable=openVar)
optionmenu.add_checkbutton(label='多選項(xiàng)2', command=callback, variable=saveVar)
optionmenu.add_checkbutton(label='多選項(xiàng)3', command=callback, variable=quitVar)
menubar.add_cascade(label='選項(xiàng)(C)', menu=optionmenu)


#主菜單:單選√ radiobutton(下拉菜單)
otherVar = IntVar()
othermenu = Menu(menubar, tearoff=False)
othermenu.add_radiobutton(label='單選項(xiàng)1', command=callback, variable=otherVar, value=1)
othermenu.add_radiobutton(label='單選項(xiàng)2', command=callback, variable=otherVar, value=2)
othermenu.add_radiobutton(label='單選項(xiàng)3', command=callback, variable=otherVar, value=3)
menubar.add_cascade(label='其他(C)', menu=othermenu)


#內(nèi)部菜單:按鈕菜單 Menubutton
mb = Menubutton(root, text='按鈕菜單...', relief=RAISED)
mb.pack()
openVar = IntVar()
saveVar = IntVar()
quitVar = IntVar()
optionmenu = Menu(mb, tearoff=False)
optionmenu.add_checkbutton(label='test', command=callback, variable=openVar)
optionmenu.add_checkbutton(label='test', command=callback, variable=saveVar)
optionmenu.add_checkbutton(label='test', command=callback, variable=quitVar)
mb.config(menu=optionmenu)


#內(nèi)部菜單:選項(xiàng)菜單 OptionMenu
variable = StringVar()
variable.set('one') ?#默認(rèn)顯示one
w = OptionMenu(root, variable, 'one', 'two', 'three')
w.pack()


#將列表添加到選項(xiàng)菜單 OptionMenu
OPTIONS = [
? ? '表項(xiàng)1',
? ? '對(duì)比2',
? ? '選項(xiàng)3',
? ? '其他4',
? ? '退出5'
? ? ]
var = StringVar()
var.set(OPTIONS[0])
o = OptionMenu(root, var, *OPTIONS) ?#*星號(hào)解包可變參數(shù)列表為逐個(gè)元素
o.pack()


#主菜單:幫助
helpmenu = Menu(menubar, tearoff=False)
helpmenu.add_separator() ?#分割線
helpmenu.add_command(label='關(guān)于...', command=callback)
helpmenu.add_separator() ?#分割線
menubar.add_cascade(label='幫助(F1)', menu=helpmenu)


#彈出菜單(暫用編輯菜單作為右鍵)
frame = Frame(root, width=512, height=512)
frame.pack()
def popup(event):
? ? editmenu.post(event.x_root, event.y_root)
frame.bind('<Button-3>', popup) ?#Button-3為鼠標(biāo)右鍵,1為左鍵,2為中鍵


root.config(menu=menubar) ?#menu參數(shù)會(huì)將菜單設(shè)置添加到root根窗口


mainloop()


示例31:事件綁定 bind (鼠標(biāo)/按鍵/按鍵組合)
from tkinter import *


root = Tk()
root.title('Event bind')


frame = Frame(root, width=200, height=200)
#鼠標(biāo)響應(yīng)事件
def callback1(event): ?#event形參獲取事件描述,必備參數(shù)
? ? print('點(diǎn)擊位置:', event.x, event.y)
frame.bind('<Button-1>', callback1) ?#Button表示鼠標(biāo)點(diǎn)擊事件, 12345分別代表左中右鍵上滾下滾
frame.pack()


#鍵盤(pán)響應(yīng)事件
def callback2(event):
? ? print(event.keysym) ?#打印信息在IDLE, keysym指鍵盤(pán)所有按鍵
frame.bind('<Key>', callback2)
frame.focus_set()
frame.pack()


#鼠標(biāo)即時(shí)響應(yīng)事件
def callback3(event):
? ? print('點(diǎn)擊位置:', event.x, event.y)
frame.bind('<Motion>', callback3) ?#鼠標(biāo)在窗口內(nèi)只要有移動(dòng)就一直輸出位置
frame.pack()


#事件序列(按鍵組合),語(yǔ)法:<modifier-type-detail> 如
#點(diǎn)擊鼠標(biāo)左鍵:<Button-1> ?ButtonRelease更安全,移除組件釋放點(diǎn)擊時(shí)不去觸發(fā)
#點(diǎn)擊H字母按鍵:<KeyPress-H>
#同時(shí)點(diǎn)擊Ctrl+Shift+H:<Control-Shift-KeyPress-H>
mainloop()


示例32:消息組件 Message | 輸入組件 Spinbox
from tkinter import *


root = Tk()
root.title('Module')


#消息組件:Message
m1 = Message(root, text='這是一個(gè)消息:', width=100)
m1.pack()


m2 = Message(root, text='這是一\n則駭人聽(tīng)聞的長(zhǎng)長(zhǎng)長(zhǎng)長(zhǎng)長(zhǎng)長(zhǎng)長(zhǎng)消息!', width=100)
m2.pack()


#輸入組件:Spinbox ?(可指定輸入范圍)
s1 = Spinbox(root, from_=0, to=5)
s1.pack()
s2 = Spinbox(root, values=('zero', 'one', 'two', 'three', 'four', 'five'))
s2.pack()


mainloop()


示例33:窗口布局管理器 PanedWindow
from tkinter import *


root = Tk()
root.title('Module')


#二窗格
'''
p = PanedWindow(orient=VERTICAL)
p.pack(fill=BOTH, expand=1)


top = Label(p, text='top pane')
p.add(top)


bottom = Label(p, text='bottom pane')
p.add(bottom)
'''
#三窗格,同時(shí)顯示隱藏布局線(showhandle=True, sashrelief=SUNKEN)
p = PanedWindow(showhandle=True, sashrelief=SUNKEN)
p.pack(fill=BOTH, expand=1)


left = Label(p, text='left pane')
p.add(left)


q = PanedWindow(orient=VERTICAL, showhandle=True, sashrelief=SUNKEN)
p.add(q)


top = Label(q, text='top pane')
q.add(top)
bottom = Label(q, text='bottom pane')
q.add(bottom)


mainloop()


示例34:容器組件 Toplevel (創(chuàng)建頂級(jí)窗口,即彈出窗口)
from tkinter import *


root = Tk()
root.title('Toplevel')


def create():
? ? top = Toplevel()
? ? #top.attributes('-alpha', 0.5) 設(shè)置彈出的頂級(jí)窗口透明度:50%
? ? top.title('Toplevel demo...')


? ? msg = Message(top, text='I love python...')
? ? msg.pack()


Button(root, text='創(chuàng)建頂級(jí)窗口', command=create).pack() ?#點(diǎn)擊出現(xiàn)頂級(jí)窗口


mainloop()


示例35:幾何管理類,包pack(),網(wǎng)格grid(),位置place()
#pack() ?注意pack和grid不要混合使用
from tkinter import *


root = Tk()
root.title('pack')


#Listbox完全填充測(cè)試
listbox = Listbox(root)
listbox.pack(fill=BOTH, expand=True) ?#fill=BOTH將窗口填滿
for i in range(10):
? ? listbox.insert(END, str(i))


#Label縱向填充
Label(root, text='red', bg='red', fg='white').pack(fill=X)
Label(root, text='green', bg='green', fg='black').pack(fill=X)
Label(root, text='blue', bg='blue', fg='white').pack(fill=X)


#Label橫向填充
Label(root, text='red', bg='red', fg='white').pack(side=LEFT)
Label(root, text='green', bg='green', fg='black').pack(side=LEFT)
Label(root, text='blue', bg='blue', fg='white').pack(side=LEFT)


mainloop()


#grid() ?注意pack和grid不要混合使用
from tkinter import *


root = Tk()
root.title('grid')


#兩個(gè)sticky=W實(shí)現(xiàn)第一列左對(duì)齊
Label(root, text='用戶名').grid(row=0, sticky=W)
Label(root, text='密碼').grid(row=1, sticky=W)


#rowspan=2可以讓圖片橫跨2行
photo = PhotoImage(file='tk_image.png')
Label(root, image=photo).grid(row=0, column=2, rowspan=2, padx=5, pady=5)


Entry(root).grid(row=0, column=1)
Entry(root, show='*').grid(row=1, column=1)


def callback():
? ? print('登陸中...')


#columnspan=3可以讓按鈕橫跨3列
Button(text='提交', width=10, command=callback).grid(row=2, columnspan=3, pady=5)


mainloop()


#place() ? 可以實(shí)現(xiàn)一些pack和grid實(shí)現(xiàn)不了的布局
from tkinter import *


root = Tk()
root.title('place')


#place位置布局測(cè)試
'''
photo = PhotoImage(file='tk_image.png')
Label(root, image=photo).pack() ?#按鈕就會(huì)出現(xiàn)在圖片的組件上,實(shí)現(xiàn)組件疊加顯示


def callback():
? ? print('正中靶心!!!')


#relx,rely相對(duì)父組件root的位置,0.5正中間,1最右邊,0最左邊,anchor=CENTER居中顯示
Button(root, text='射擊', command=callback).place(relx=0.5, rely=0.5, anchor=CENTER)
'''
Label(root, bg='red').place(relx=0.5, rely=0.5, relheight=0.75, relwidth=0.75, anchor=CENTER)
Label(root, bg='yellow').place(relx=0.5, rely=0.5, relheight=0.5, relwidth=0.5, anchor=CENTER)
Label(root, bg='blue').place(relx=0.5, rely=0.5, relheight=0.25, relwidth=0.25, anchor=CENTER)


mainloop()


示例35:對(duì)話框 (警告 showinfo | 消息 messagebox | 文件 filedialog | 顏色 colorchooser)
from tkinter import *
from tkinter import messagebox ? ?#messagebox()需要單獨(dú)導(dǎo)入
from tkinter import filedialog ? ?#filedialog()需要單獨(dú)導(dǎo)入
from tkinter import colorchooser ?#colorchooser()需要單獨(dú)導(dǎo)入
from tkinter.messagebox import * ?#用戶使用showinfo()


#警告對(duì)話框
showinfo(title='test', message='警告')


#消息對(duì)話框
result = messagebox.askokcancel('demo', '發(fā)射核彈?') ?#返回值是True或False
print(result) ?#根據(jù)用戶按下了確定還是取消做進(jìn)一步的操作


#文件對(duì)話框
root = Tk()
def callback1():
? ? filename = filedialog.askopenfilename(defaultextension='.py') ?#指定文件后綴
? ? print(filename) ?#返回的是文件的完整路徑


Button(root, text='打開(kāi)文件', command=callback1).pack()


#顏色選擇對(duì)話框
def callback2():
? ? color_data = colorchooser.askcolor() ?#調(diào)用windows的顏色選擇器
? ? print(color_data) ?#選擇紅色打印:((255.99609375, 0.0, 0.0), '#ff0000')


Button(root, text='選擇顏色', command=callback2).pack()


mainloop()





總結(jié)

以上是生活随笔為你收集整理的【python】速查手册(基础笔记) - 人生苦短,我用python的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。