【python】速查手册(基础笔记) - 人生苦短,我用python
生活随笔
收集整理的這篇文章主要介紹了
【python】速查手册(基础笔记) - 人生苦短,我用python
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
python學(xué)習(xí)筆記:小甲魚python全套視頻 ?+ ?python基礎(chǔ)教程 第2版修訂版(書附10個大型案例)
python學(xué)習(xí)環(huán)境:(python3)win10下python3.5.4的IDLE ?+ ?ubuntu下python3輔助
python分享范圍:適合有C/C++/JAVA任意語言之一為基礎(chǔ),不適合純新手入門
python語言優(yōu)勢:至今還沒有一門編程語言,開發(fā)速度比Python快,運行速度比C快
python常用工具手冊:
http://bbs.fishc.com/forum.php?mod=collection&action=view&ctid=198
---------------------------------2017.08.27--------------------------------------
00丶python背景與特點
Python語言起源
在1989年末,Guido van Rossum為了打發(fā)圣誕節(jié)的無聊,創(chuàng)造了python(大蟒蛇)。 1991年,第一個 Python 版本誕生。最新版本是Python3 3.6.2 。Guido van Rossum 是蒙提·派森的飛行馬戲團(Monty Python‘s Flying Circus)的愛好者。logo是由兩只蟒蛇的圖形組成。
官網(wǎng)下載地址:
https://www.python.org/downloads/
Python 3 與 Python 2 不完全兼容
官方表示對 Python2 支持到2020年, Python2 2.7.13。Python 2 的生態(tài)庫遠遠大于 Python 3。
簡單:
學(xué)習(xí)曲線平滑, 45分鐘學(xué)會基本使用,使用簡單。
跨平臺:
一次編寫、到處運行。 Windows, Linux, Mac, Android
功能強大:
? ? 動態(tài)類型、自動內(nèi)存管理
? ? 非常實用的內(nèi)置對象類型
? ? 強大的內(nèi)置工具和標準庫
? ? 易于擴展,很多成熟易用第三方庫
? ? 大型程序支持
應(yīng)用廣泛:
? ? 數(shù)據(jù)庫、網(wǎng)絡(luò)、圖形圖像、科學(xué)計算、機器學(xué)習(xí)、web開發(fā)、操作系統(tǒng)擴展等
缺點:
運行速度不夠快(硬件的發(fā)展可以為此彌補不足)
開發(fā)速度與運行速度之間的矛盾:
至今還沒有一門編程語言,開發(fā)速度比Python快,運行速度比C快
知名軟件包:Django/Numpy/Pandas/Matplotlib/PIL (Pillow)/PyQt5/Tensorflow/Scipy/Theano/NLTK
知名項目:(網(wǎng)站)豆瓣/知乎/美團/Gmail/Youtube/Instagram/Calibre/……
01丶第一次親密接觸 first love
(1) win下的python IDLE集成開發(fā)環(huán)境自動縮進,table鍵補齊變量名
(2) linux下使用vi編輯.py的python文件,需要聲明 #!/usr/bin/python3
(3) python使用等量(1個tab)的縮進來嚴格對齊表示作用域
#!/usr/bin/python3
#guess game
print ("---------游戲開始-----------")
temp = input ("輸入一個我現(xiàn)在想的數(shù)字:")
guess = int (temp)
if guess == 8:
print ("猜對了!!!")
else:
print ("哈哈,猜錯了。。")
print ("游戲結(jié)束嘍~")
#---end---
BIF == Built-in functions(內(nèi)置函數(shù))
>>> dir(__builtins__)
..., 'input', ...
>>> help(input)
#可以查詢內(nèi)置函數(shù)的說明和用法,類似于C語言的man手冊
02丶變量 variable
(1) python沒有"變量"只有"名字"
(2) 變量使用之前,需要對其先賦值
(3) 變量名命名同C的規(guī)則,不能以數(shù)字開頭,保證可讀性命名即可
(4) 大小寫敏感,區(qū)分
(5) =左右依次為左值和右值
(6) 十六進制,以0x 或 0X 開頭 ,數(shù)字由"0"到"9" 或者 "a"到"f" 或者 "A"到"F"組成
八進制,0o或0O 開頭,數(shù)字由"0" 到 "7"組成
二進制,0b或0B 開頭表示,數(shù)字由"0" 或者"1"組成
十進制由數(shù)字"0"到"9"組成,并且不能以0開頭
>>> 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ōu)先級 precedence of operator
#符合數(shù)學(xué)運算優(yōu)先原則,括號最優(yōu)先,最安全。
lambda lambda表達式
or 布爾或
and 布爾與
not 布爾非
in 和 not in 成員是否屬于測試
is 和 is not 對象是否是同一個
> ?>= ?< ?<= ?== ?!= 比較操作符
| 按位或
^ 按位異或
& 按位與
<< 和 >> 移位
+ 和 - 加法和減法
* 和 / 和 % 乘法、除法、取余
+x 和 -x 正負號
~x 按位翻轉(zhuǎn)
** 指數(shù)(冪運算)
// 地板除法,舍棄小數(shù)部分
---python運算符優(yōu)先級(圖)---
#=連續(xù)賦值,自右向左,同C語言
>>> 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)、浮點型(float)、布爾類型(bool)、e記法(科學(xué)計數(shù)法,屬于float)
(1) 整型與浮點型的區(qū)別就是是否含有小數(shù)點'.'
(2) bool類型的值是以大寫開頭的兩個單詞: True / False
(3) 純數(shù)字的字符串可以使用int轉(zhuǎn)為數(shù)字,進而參與計算,相當(dāng)于C的atoi,非純數(shù)字的不能使用int轉(zhuǎn)換為數(shù)字
(4) float類型轉(zhuǎn)換為int類型時,會丟棄小數(shù)部分
(5) str類型均可被其他類型轉(zhuǎn)換,即變成字符串無障礙
(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)鍵字后面的條件為假的時候,程序自動崩潰并拋出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以空格隔開
s t r i n g
range()函數(shù)
range ([start], [stop], [step]) ?#step默認每次遞增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語言的break和continue,依次為跳出循環(huán)和跳過當(dāng)前循環(huán)。
pass 和 del 和 exec
pass 什么也不敢,暫時預(yù)留
del 刪除不再使用的對象
exec 執(zhí)行python語句
exal 計算python表達式,并返回結(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()
功能:列表長度(元素個數(shù))
len(listname)
>>> len(member)
4
append()
功能:向列表添加單個元素
listname.append(element)
>>> member.append('class')
>>> member
['name', 'id', 'age', 'weight', 'class']
extend()
功能:使用子列表擴展列表
listname.extend([element1, element2, ...])
>>> member.extend (['str1', 'str2'])
>>> member
['name', 'id', 'age', 'weight', 'class', 'str1', 'str2']
insert()
功能:向列表指定位置插入元素
listname.insert(position, element)
#list和數(shù)組一樣,下標/索引均從0開始
>>> member.insert (1, 'new_elem')
>>> member
['name', 'new_elem', 'id', 'age', 'weight', 'class', 'str1', 'str2']
列表元素訪問
listname[index]
#index從0開始,到index-1位置的索引訪問
列表元素刪除
listname.remove(element) #刪除元素element
del listname[index] #刪除index位置的元素
listname.pop() #刪除最后一個元素,相當(dāng)于C語言的彈棧
listname.pop(index) #刪除index位置指定的元素
列表元素分片
listname[start_index:stop_index]
(1) 分片不會修改原列表的值,輸出的是一份拷貝
(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)] #訪問最后3個元素
['str1', 'str2', 'str3']
>>> member[0:len(member):2] #最后的2代表步長
['name', 'age', 'class', 'str2']
列表常用操作符
(1) list元素的判斷只會判斷第一個元素,然后理解返回bool結(jié)果
(2) list支持比較、邏輯、連接(+)、重復(fù)(*)、成員關(guān)系(in)操作符
(3) list賦值list時需要注意加上[:],左值會表現(xiàn)為一份拷貝
示例:
list2 = list1[:]#list2是list1的一份拷貝
list3 = list1 #list3是list1的一個引用(list1被修改,list3也會跟著被修改)
(4) dir(list) 查看list支持的所有方法:
listname.count(element)#element元素出現(xiàn)的次數(shù)
listname.index(element, [range_s], [rang_t])#查找元素在起止范圍里第一次出現(xiàn)的下標位置
listname.reverse()#將list中的元素原地翻轉(zhuǎn)
listname.sort()#將list中的元素進行排序,默認從小到大(修改原list內(nèi)容)
listname.sort(reverse=True)#排序元素,實現(xiàn)從大到小(修改原list內(nèi)容)
07丶元組 tuple
元組和列表使用上相似:
(1) 最大區(qū)別:列表可以任意修改和插入等操作,元組是不可改變的
(2) 創(chuàng)建:列表使用[],元組使用()
元組只有1個元素時使用(element,)注意逗號
()可以省略,但是,逗號不能省略
(3) 訪問:都使用name[index]來訪問
(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) \可以進行符號轉(zhuǎn)義
(2) 單引號等同于雙引號
(3) 定義字符串時使用r寫在右值前面聲明為原始字符串
(4) 使用三引號('''或""")可以指定多行字符串。并且字符串里可以包含單引號和雙引號'''
(5) +號運算符可以連接字符串為1個字符串
(6) *號運算符可以復(fù)制多個相同字符串
列表和元組應(yīng)用于字符串,所有標準的序列操作均適用于字符串。
>>> 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() 返回新字符串,把字符串的第一個字符改為大寫
casefold() 返回新字符串,把整個字符串的所有字符改為小寫
center(width) 將字符串居中,并使用空格填充至長度 width 的新字符串
count(sub[, start[, end]]) 返回 sub 在字符串里邊出現(xiàn)的次數(shù),start 和 end 參數(shù)表示范圍,可選。
encode(encoding='utf-8', errors='strict') 以 encoding 指定的編碼格式對字符串進行編碼。
endswith(sub[, start[, end]]) 檢查字符串是否以 sub 子字符串結(jié)束,如果是返回 True,否則返回 False。start 和 end 參數(shù)表示范圍,可選。
expandtabs([tabsize=8]) 把字符串中的 tab 符號(\t)轉(zhuǎn)換為空格,如不指定參數(shù),默認的空格數(shù)是 tabsize=8。
find(sub[, start[, end]]) 檢測 sub 是否包含在字符串中,如果有則返回索引值,否則返回 -1,start 和 end 參數(shù)表示范圍,可選。
index(sub[, start[, end]]) 跟 find 方法一樣,不過如果 sub 不在 string 中會產(chǎn)生一個異常。
isalnum() 如果字符串至少有一個字符并且所有字符都是字母或數(shù)字則返回 True,否則返回 False。
isalpha() 如果字符串至少有一個字符并且所有字符都是字母則返回 True,否則返回 False。
isdecimal() 如果字符串只包含十進制數(shù)字則返回 True,否則返回 False。
isdigit() 如果字符串只包含數(shù)字則返回 True,否則返回 False。
islower() 如果字符串中至少包含一個區(qū)分大小寫的字符,并且這些字符都是小寫,則返回 True,否則返回 False。
isnumeric() 如果字符串中只包含數(shù)字字符,則返回 True,否則返回 False。
isspace() 如果字符串中只包含空格,則返回 True,否則返回 False。
istitle() 如果字符串是標題化(所有的單詞都是以大寫開始,其余字母均小寫),則返回 True,否則返回 False。
isupper() 如果字符串中至少包含一個區(qū)分大小寫的字符,并且這些字符都是大寫,則返回 True,否則返回 False。
join(sub) 以字符串作為分隔符,插入到 sub 中所有的字符之間。
ljust(width) 返回一個左對齊的字符串,并使用空格填充至長度為 width 的新字符串。
lower() 轉(zhuǎn)換字符串中所有大寫字符為小寫。
lstrip() 去掉字符串左邊的所有空格
partition(sub) 找到子字符串 sub,把字符串分成一個 3 元組 (pre_sub, sub, fol_sub),如果字符串中不包含 sub 則返回 ('原字符串', '', '')
replace(old, new[, count]) 把字符串中的 old 子字符串替換成 new 子字符串,如果 count 指定,則替換不超過 count 次。
rfind(sub[, start[, end]]) 類似于 find() 方法,不過是從右邊開始查找。
rindex(sub[, start[, end]]) 類似于 index() 方法,不過是從右邊開始。
rjust(width) 返回一個右對齊的字符串,并使用空格填充至長度為 width 的新字符串。
rpartition(sub) 類似于 partition() 方法,不過是從右邊開始查找。
rstrip() 刪除字符串末尾的空格。
split(sep=None, maxsplit=-1) 不帶參數(shù)默認是以空格為分隔符切片字符串,如果 maxsplit 參數(shù)有設(shè)置,則僅分隔 maxsplit 個子字符串,返回切片后的子字符串拼接的列表。
splitlines(([keepends])) 按照 '\n' 分隔,返回一個包含各行作為元素的列表,如果 keepends 參數(shù)指定,則返回前 keepends 行。
startswith(prefix[, start[, end]]) 檢查字符串是否以 prefix 開頭,是則返回 True,否則返回 False。start 和 end 參數(shù)可以指定范圍檢查,可選。
strip([chars]) 刪除字符串前邊和后邊所有的空格,chars 參數(shù)可以定制刪除的字符,可選。
swapcase() 翻轉(zhuǎn)字符串中的大小寫。
title() 返回標題化(所有的單詞都是以大寫開始,其余字母均小寫)的字符串。
translate(table) 根據(jù) table 的規(guī)則(可以由 str.maketrans('a', 'b') 定制)轉(zhuǎn)換字符串中的字符。
upper() 轉(zhuǎn)換字符串中的所有小寫字符為大寫。
zfill(width) 返回長度為 width 的字符串,原字符串右對齊,前邊用 0 填充。
字符串操作:格式化
(1) 通過format方法將位置參數(shù)傳遞給對應(yīng)字段
(2) : 冒號表示格式化符號的開始
位置參數(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ù)必須在關(guān)鍵字參數(shù)的前面。
字符串格式化符號含義
%c 格式化字符及其 ASCII 碼
%s 格式化字符串
%d 格式化整數(shù)
%o 格式化無符號八進制數(shù)
%x 格式化無符號十六進制數(shù)
%X 格式化無符號十六進制數(shù)(大寫)
%f 格式化浮點數(shù)字,可指定小數(shù)點后的精度,默認精確到小數(shù)點后6位
%e 用科學(xué)計數(shù)法格式化浮點數(shù)
%E 作用同 %e,用科學(xué)計數(shù)法格式化浮點數(shù)
%g 根據(jù)值的大小決定使用 %f 或 %e
%G 作用同 %g,根據(jù)值的大小決定使用 %f 或者 %E
舉例:
>>> '%c' % 97 # 此處 % 為占位符,同C語言中printf函數(shù)中的%
'a'
>>> '%c %c %c' % (97, 98, 99) #此處的元組()小括號不能省略
'a b c'
格式化操作符輔助命令
m.n m 是顯示的最小總寬度,n 是小數(shù)點后的位數(shù)
- 用于左對齊
+ 在正數(shù)前面顯示加號(+)
# 在八進制數(shù)前面顯示 '0o',在十六進制數(shù)前面顯示 '0x' 或 '0X'
0 顯示的數(shù)字前面填充 '0' 取代空格
舉例:
>>> '%5.1f' % 27.658 #m.n
' 27.7'
>>> '%-10d' % 5 #填充的位數(shù)都是空格
'5 ? ? ? ? ?'
>>> '%#x' % 160 #對應(yīng)進制顯示方式
'0xa0'
>>> '%010d' % 5 #用0填充。'%-010d' % 5 負號的時候填充的只會是空格
'0000000005'
Python 的轉(zhuǎn)義字符及其含義
\' 單引號
\" 雙引號
\a 發(fā)出系統(tǒng)響鈴聲
\b 退格符
\n 換行符
\t 橫向制表符(TAB)
\v 縱向制表符
\r 回車符
\f 換頁符
\o 八進制數(shù)代表的字符
\x 十六進制數(shù)代表的字符
\0 表示一個空字符
\\ 反斜杠
09丶序列方法 sequence method
列表、元組、字符串的共同點:
(1) 都可以通過索引得到每一個元素
(2) 默認索引值總是從0開始
(3) 可以通過分片的方法得到一個范圍內(nèi)的元素的集合
(4) 有很多共同的操作符(重復(fù)*、拼接+、成員關(guān)系in/not in等)
(5) 統(tǒng)稱為序列,以下(成員函數(shù))為序列方法
list()
list(iterable) 把一個可迭代對象轉(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) 把一個可迭代對象轉(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ù),會加在一起
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)一個序列的內(nèi)容
>>> reversed(sequence)
舉例:
>>> numbers = [1, 24, 5, -98, 54, 32]
>>> reversed(numbers)
<list_reverseiterator object at 0x000002C3EE5046A0>#這種格式都是:迭代器對象
>>> list(reversed(numbers)) # 將迭代器對象轉(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(...) 返回由各個參數(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): ?#并行迭代,同時迭代兩個變量
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)沒有過程(no return)
(2) 函數(shù)返回多個值的時候,使用list列表或tuple元組進行返回
(3) 局部變量和全局變量的規(guī)則同C語言
(4) 在函數(shù)內(nèi)部使用 global 修飾變量,使函數(shù)可以修改同名的全局變量
(5) 函數(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): #形參:多個參數(shù)使用,逗號隔開
#函數(shù)體使用參數(shù)param
function_name(parameter) #實參:傳遞實際參數(shù)
函數(shù)文檔
舉例:
>>> def my_sec_func(name):
'function document.'#函數(shù)文檔部分,單引號引起來即可
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ù)與默認參數(shù)
舉例:
>>> def say_some(name, words):
#>> def say_some(name='abc', words='string'): #形參可設(shè)置默認值
print(name + ' -> ' + words)
>>> say_some('Jan', 'learning python.')
Jan -> learning python.
>>> say_some(words='learning python.', name='Jan') #指定形參對應(yīng)實參
Jan -> learning python.
#>>> say_some()
#abc -> string
*params搜集其余的位置參數(shù)
>>> def test(*params): # *params把實參打包為元組
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) #注意傳參需要單獨指定
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...
閉包closure
舉例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] #對func2函數(shù)來說x是全局變量,在func2中沒有定義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 表達式(匿名函數(shù))
(1) 不需要考慮函數(shù)名的命名問題
(2) 極大簡化函數(shù)編寫的步驟
舉例:
>>> def ds(x):
return 2*x + 1
>>> ds(5)
11
>>> lambda x : 2*x + 1
<function <lambda> at 0x000002170B3D87B8> #可以理解為返回的是C語言的函數(shù)指針
>>> g = lambda x : 2*x + 1 #賦值后,傳參即可,g相當(dāng)于接收了匿名函數(shù)
>>> g(5)
11
>>> g = lambda x, y : x+y #lambda匿名函數(shù)多個參數(shù)
>>> g(1, 3)
4
兩個牛逼的BIF:filter和map
(1) filter 過濾:返回其函數(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] #驗證filter過濾的是非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))) ?#簡化一行實現(xiàn)求奇數(shù)
[1, 3, 5, 7, 9]
(2) map 映射:對序列中每個元素都應(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語言
? ? else:
? ? ? ? return n * factorial(n-1) #(2)必須調(diào)用函數(shù)自身,同C語言
number = int(input("請輸入一個正整數(shù):"))
result = factorial(number)
print("%d 的階乘為:%d" % (number, result))
#運行:
請輸入一個正整數(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("請輸入一個數(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個盤子從x移動到y(tǒng)上
? ? ? ? print(x, '-->', z) ? ? ?#將最底下的最后一個盤子從x移動到z上
? ? ? ? hanoi(n-1, y, x, z) ? ? #將y上的n-1個盤子移動到z上
n = int(input('請輸入漢諾塔的層數(shù):'))
hanoi(n, 'x', 'y', 'z')
---------------------------------2017.08.29--------------------------------------
12丶字典 dict
(1) 字典是一種映射類型(key:value 鍵值映射項),類型名為 dict
(2) 字典的表示使用{}大括號,元素映射之間使用:冒號,使用dictname[]訪問字典映射的值
(3) 新建字典有兩種方法:三層小括號,一層小括號中key=value
(4) 字典中的鍵值映射項是無序的,popitem時是隨機彈出
(5) 字典基本操作:
len(d) 返回d中項的數(shù)量
d[k] 返回映射到鍵k上的值
d[k]=v 將值v映射到鍵k上
del d[k] 刪除鍵為k的項
k in d 檢查d中是否含有鍵為k的項
(6) 字典常用方法: clear()/copy()/fromkeys()/get()/has_key()/items()/iteritems()/keys()/iterkeys()/pop()/popitem()/setdefault()/update()/values()/itervalues()
映射關(guān)系示例
>>> brand = ['李寧', '耐克', '阿迪達斯', 'xx工作室']
>>> slogan = ['一切皆有可能', 'Just do it', 'Impossible is nothing', '讓編程改變世界']
>>> print('魚c工作室的口號是: ', slogan[brand.index('xx工作室')])
xx工作室的口號是: ?讓編程改變世界
#使用字典來完成映射工作
>>> dict1 = {'李寧':'一切皆有可能', '耐克':'Just do it', '阿迪達斯':'Impossible is nothing', 'xx工作室':'讓編程改變世界'}
>>> print('xx工作室的口號是: ', dict1['xx工作室'])
xx工作室的口號是: ?讓編程改變世界
#新建一個字典方法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}
#新建一個字典方法2:(key1=value1, key2=value2, ...)
>>> dictname = dict(蒼井空='讓AV改變宅男', 工作室='讓編程改變世界')
>>> dictname
{'工作室': '讓編程改變世界', '蒼井空': '讓AV改變宅男'}
>>> dictname['蒼井空']
'讓AV改變宅男'
#字典中新增映射元素
>>> dictname['愛迪生'] = '天才是99%的汗水+1%的靈感,但這1%的靈感比99%的汗水更重要。'
>>> dictname
{'工作室': '讓編程改變世界', '愛迪生': '天才是99%的汗水+1%的靈感,但這1%的靈感比99%的汗水更重要。', '蒼井空': '讓AV改變宅男'}
字典中鍵、值、鍵值映射項的訪問
>>> 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)建并返回一個新的字典
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'} ? #還是返回新的字典,并不會修改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但在字典里如果找不到的話會將映射項添加到字典中
dictname.setdefault(key, value)
舉例:
>>> a
{3: 'three', 4: 'four'}
>>> a.setdefault(5, '小白')
'小白'
>>> a
{3: 'three', 4: 'four', 5: '小白'}
clear() ?清空一個字典(包括使用當(dāng)前字典賦值的其他字典)
舉例:
>>> dict1.clear()
>>> dict1
{}
copy() ?拷貝一個字典(淺拷貝,不受字典修改影響)
>>> a = {1:'one', 2:'two', 3:'three'}
>>> b = a.copy()
>>> c = a #相當(dāng)于C的指針,C++的引用,修改字典c的值會同時影響字典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(...) ?給定一個鍵彈出一個值
popitem() ?隨機彈出一個項(映射關(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(...) ?使用一個子字典去更新原字典
dictname1.update(dictname2)
舉例:
>>> a
{3: 'three', 4: 'four', 5: '小白'}
>>> b = {'小白':'狗'}
>>> a.update(b)
>>> a
{'小白': '狗', 3: 'three', 4: 'four', 5: '小白'}
13丶集合 set
(1) 使用{}創(chuàng)建的沒有映射關(guān)系的字典,成為集合類型,如num = {1, 2, 3, 4, 5}
(2) 集合中元素唯一,重復(fù)的數(shù)據(jù)會被自動清理掉
(3) 集合中元素?zé)o序,不能索引取到其元素的值
(4) 集合使用關(guān)鍵字 set([]) 來創(chuàng)建
(5) 集合支持 in 和 not in 來判斷是否屬于集合
舉例:
>>> num = {}
>>> type(num)
<class 'dict'>
#set沒有體現(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無序性
>>> 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實現(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]
#簡化: 實現(xiàn)set的唯一性,并且會把set的無序性變?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)建方法(整理出來):
http://bbs.fishc.com/forum.php?mod=viewthread&tid=45276&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
14丶文件操作 file operation
open(...) ?打開一個文件返回一個流對象
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) ?#除了file參數(shù),其他參數(shù)均有默認值
'r' 只讀模式
'w' 寫入(會覆蓋已存在的文件)模式
'x' 文件存在,報異常的模式
'a' 寫入(文件存在則追加)模式
'b' 二進制模式
't' 文本模式
'+' 可讀寫模式(可添加到其他模式)
'U' 通用換行符支持
舉例:
#打開一個文件,注意路徑的中\(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'>
文件對象方法
(整理)
http://bbs.fishc.com/forum.php?mod=viewthread&tid=45279&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
(1) 文件對象支持直接使用list轉(zhuǎn)換讀出
(2) 文件對象支持 for...in 的迭代方式讀取
舉例:
>>> f = open('C:\\Users\\Jan\\Desktop\\IP.txt') #f,打開的文件流對象
>>> f.read()
'【本機】\nIP:192.168.31.217\n[ Ctrl + r ]\ncmd\nping 192.168.31.207\nmstsc\n\n\n【虛擬機】 - 虛擬網(wǎng)絡(luò)編輯器(自動) - 橋接模式\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)
'【本機】\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', '【虛擬機】 - 虛擬網(wǎng)絡(luò)編輯器(自動) - 橋接模式\n', 'IP:192.168.31.207\n', 'linux賬戶:jiangyuan\n', 'linux密碼:123456\n']
>>> for each_line in f:
print(each_line)#逐行讀取文件內(nèi)容的高效方法
【本機】
IP:192.168.31.217
[ Ctrl + r ]
cmd
ping 192.168.31.207
mstsc
...
#創(chuàng)建一個新的可寫入的文件,寫入內(nèi)容,然后關(guān)閉文件流對象
>>> f = open('C:\\Users\\Jan\\Desktop\\test.txt', 'w')
>>> f.write('some lines')
10
>>> f.close()
任務(wù):將文件record.txt中的數(shù)據(jù)進行分割并且按照規(guī)律保存起來。
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] != '======':
? ? ? ? ? ? # 我們再這里進行字符串分割操作
? ? ? ? ? ? (role, line_spoken) = each_line.split(':', 1) ?#中文冒號:否則會報錯
? ? ? ? ? ? if role == '小甲魚':
? ? ? ? ? ? ? ? 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) 使用模塊是需要進行導(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個人總資料', 'Qiyi', 'QQMusicCache', 'qycache', 'System Volume Information', 'Youku Files', 'Youxun', '博客'] ?#RECYCLE.BIN是個回收站
>>> 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') ?#運行系統(tǒng)的shell命令:windows shell窗口
-1073741510
>>> os.system('calc') ?#運行系統(tǒng)的shell命令:calc計算器
0
>>> os.curdir ?#當(dāng)前目錄('.')
'.'
>>> os.listdir(os.curdir) ?# 等同于 os.listdir('.')
['$RECYCLE.BIN', '.cache', '360Downloads', 'A', 'Jan_mi', 'Jan個人總資料', 'Qiyi', 'QQMusicCache', 'qycache', 'System Volume Information', 'Youku Files', 'Youxun', '博客']
>>> os.sep ?#輸出操作系統(tǒng)特定的路徑分隔符(Win下為'\\',Linux下為'/')
'\\'
>>> os.linesep ?#當(dāng)前平臺使用的行終止符(Win下為'\r\n',Linux下為'\n')
'\r\n'
>>> os.name ?#指代當(dāng)前使用的操作系統(tǒng)(包括:'posix', ?'nt', 'mac', 'os2', 'ce', 'java')
'nt' ?#nt是windows系統(tǒng)平臺
os.path 模塊(系統(tǒng)路徑模塊屬于os的子模塊)
>>> os.path.basename('E:\\A\\B\\C\\sexy.avi') ?#去掉目錄路徑,單獨返回文件名
'sexy.avi'
>>> os.path.dirname('E:\\A\\B\\C\\sexy.avi') ?#去掉文件名,單獨返回目錄路徑
'E:\\A\\B\\C'
>>> os.path.join('A', 'B', 'C') ?#將path1, path2...各部分組合成一個路徑名
'A\\B\\C'
>>> os.path.join('D:', 'A', 'B', 'C')
'D:A\\B\\C'
>>> os.path.join('D:\\', 'A', 'B', 'C') ?#注意盤符需要帶上斜杠
'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') ?#分離文件名與擴展名,返回(f_name, f_extension)元組
('E:\\A\\SEXY', '.AVI')
>>> os.path.getatime('E:\\A\\test.txt') ?#返回指定文件最近的訪問時間
1504103243.229383 ?#浮點型秒數(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:\\') ?#判斷指定路徑是否存在且是一個掛載點
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)容傾倒入文件流對象中
>>> 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的字典映射寫入文件
>>> pickle.dump(city, pickle_f)
>>> pickle_f.close()
>>> pickle_file = open('E:\\A\\city.pkl', 'rb') ?#使用字典的時候打開文件裝載即可
>>> city = pickle.load(pickle_file)
>>> print(city)
{'城市2': '000002', '城市n': '999999', '城市1': '000001'}
---------------------------------2017.08.31--------------------------------------
16丶異常 exception
異常匯總
AssertionError 斷言語句(assert)失敗<eg1>
AttributeError 嘗試訪問未知的對象屬性<eg2>
EOFError 用戶輸入文件末尾標志EOF(Ctrl+d)?
FloatingPointError 浮點計算錯誤?
GeneratorExit generator.close()方法被調(diào)用的時候?
ImportError 導(dǎo)入模塊失敗的時候?
IndexError 索引超出序列的范圍<eg3>
KeyError 字典中查找一個不存在的關(guān)鍵字<eg4>
KeyboardInterrupt 用戶輸入中斷鍵(Ctrl+c)?
MemoryError 內(nèi)存溢出(可通過刪除對象釋放內(nèi)存)?
NameError 嘗試訪問一個不存在的變量?
NotImplementedError 尚未實現(xiàn)的方法?
OSError 操作系統(tǒng)產(chǎn)生的異常(例如打開一個不存在的文件)?
OverflowError 數(shù)值運算超出最大限制?
ReferenceError 弱引用(weak reference)試圖訪問一個已經(jīng)被垃圾回收機制回收了的對象?
RuntimeError 一般的運行時錯誤?
StopIteration 迭代器沒有更多的值?
SyntaxError Python的語法錯誤?
IndentationError 縮進錯誤?
TabError Tab和空格混合使用?
SystemError Python編譯器系統(tǒng)錯誤?
SystemExit Python編譯器進程被關(guān)閉?
TypeError 不同類型間的無效操作?
UnboundLocalError 訪問一個未初始化的本地變量(NameError的子類)?
UnicodeError Unicode相關(guān)的錯誤(ValueError的子類)?
UnicodeEncodeError Unicode編碼時的錯誤(UnicodeError的子類)?
UnicodeDecodeError Unicode解碼時的錯誤(UnicodeError的子類)?
UnicodeTranslateError Unicode轉(zhuǎn)換時的錯誤(UnicodeError的子類)?
ValueError 傳入無效的參數(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 #斷言語句(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'#嘗試訪問未知的對象屬性
>>> 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' #字典中查找一個不存在的關(guān)鍵字
>>> my_dict.get('four')
>>> #dict.get(...)方法比較安全合適
異常檢測與處理
(1) try語句一旦檢測出現(xiàn)異常,則剩下的其他代碼則不會執(zhí)行
(2) raise Exception_name 主動引發(fā)一個自定義異常名字的異常,可定義異常描述
try:
#檢測范圍
except Exception[as reason]:
#出現(xiàn)異常(Exception)后的處理代碼
finally:
#無論如何都會被執(zhí)行的代碼(收尾工作)
舉例:
try:
? ? f = open('我為什么是一個文件.txt')
? ? print(f.read())
? ? f.close()
except OSError:
? ? print('文件出錯啦T_T')
運行:
文件出錯啦T_T
try:
? ? f = open('我為什么是一個文件.txt')
? ? print(f.read())
? ? f.close()
except OSError as reason:
? ? print('文件出錯啦T_T\n錯誤的原因是:' + str(reason))
運行:
文件出錯啦T_T
錯誤的原因是:[Errno 2] No such file or directory: '我為什么是一個文件.txt'
try:
? ? sum = 1 + '1'
? ? f = open('我為什么是一個文件.txt')
? ? print(f.read())
? ? f.close()
except (OSError, TypeError): ?#多個異常同時捕獲
? ? print('出錯啦T_T')
運行:出錯啦T_T
try:
? ? f = open('我為什么是一個文件.txt', 'w')
? ? print(f.write('我存在了!')) ?#沒有finally時并不會寫入文件
? ? sum = 1 + '1'
? ? f.close()
except (OSError, TypeError):
? ? print('出錯啦T_T')
finally:
? ? f.close()
運行:
5
出錯啦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-簡潔的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)完沒有break就會執(zhí)行else
? ? ? ? print('%d是素數(shù)!' % num)
num = int(input('請輸入一個數(shù):'))
showMaxFactor(num)
舉例:try-else
try:
? ? print(int('123'))
except ValueError as reason:
? ? print('出錯啦:' + str(reason))
else:
? ? print('Good!沒有任何異常。')
運行:
123
Good!沒有任何異常。
with as
舉例:
try:
? ? with open('data.txt', 'w') as f: #比 f = open(...) 多了文件不使用時自動關(guān)閉功能
? ? for each_line in f:
? ? ? ? print(each_line)
except OSError as reason:
? ? print('出錯啦:' + str(reason))
#finally: ? ? ? #有了with就不需要finally去調(diào)用關(guān)閉,會自動關(guān)閉
# ? ?f.close() ?#如果文件data.txt不存在就試圖去關(guān)閉一個不存在的文件
18丶圖形用戶界面 EasyGui
EasyGui官網(wǎng):http://easygui.sourceforge.net
中文的教學(xué)文檔:http://bbs.fishc.com/thread-46069-1-1.html (要看完并實操)
模塊庫: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è)置-以管理員身份運行此程序-確定
> "C:\Program Files (x86)\python\python.exe" setup.py install
#生成了文件模塊庫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 出錯~!!!
【解決辦法】
(1) 重裝python IDLE勾選添加python路徑,選擇目錄安裝到C:\python文件夾,如重裝則忽略(2),如此一來win-cmd下的python中sys.path和IDLE中的sys.path則一致了。
(2) 對比windows命令窗口中啟動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)入模塊的同時重定義模塊名字
>>> g.msgbox('嗨,python!')
'OK'
>>>?
# No error, success... 但每次重啟IDLE都需要將windows下的sys.path進行添加。
# 示例,gui界面文字小游戲
import easygui as g
import sys
while 1:
? ? ? ? g.msgbox("嗨,歡迎進入第一個界面小游戲^_^")
? ? ? ? msg ="請問你希望在魚C工作室學(xué)習(xí)到什么知識呢?"
? ? ? ? title = "小游戲互動"
? ? ? ? choices = ["談戀愛", "編程", "OOXX", "琴棋書畫"]
? ? ? ??
? ? ? ? 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 = "你希望重新開始小游戲嗎?"
? ? ? ? title = "請選擇"
? ? ? ??
? ? ? ? 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丶類和對象 class and object
面向?qū)ο?Object Oriented)
(1) python約定類名以大寫字母開頭
(2) 面向?qū)ο筇卣?#xff1a;封裝(信息隱蔽)、繼承(子類共享父類公共內(nèi)容)、多態(tài)(不同對象對同一方法響應(yīng)不同的行動)
類的示例:
class Turtle:
#屬性
color = 'green'
weight = 60
legs = 2
shell = True
age = 26
#方法
def climb(self):
print('我正在學(xué)習(xí)...')
def run(self):
print('我正在奔跑...')
運行:
>>> tt = Turtle() ?#類Turtle的示例對象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對象中
>>> list1
[1, 2, 3, 5, 7]
>>> list1.append(9) ?#append() 方法封裝在list1對象中
>>> 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() ?#不同對象對同一方法響應(yīng)不同的行動
我是小A
>>> b.fun() ?#不同對象對同一方法響應(yīng)不同的行動
我是小B
self
相當(dāng)于C++的this指針(指向當(dāng)前對象本身的地址),表明類自身
舉例:
>>> class Ball:
def setName(self, name): ?#默認self的寫法
self.name = name
def kick(self): ?#默認self的寫法
print('我叫%s, 該死的誰踢我...' % self.name)
>>> a = Ball()
>>> a.setName('球A')
>>> b = Ball()
>>> b.setName('球B')
>>> c = Ball()
>>> c.setName('土豆')
>>> a.kick()
我叫球A, 該死的誰踢我...
>>> c.kick()
我叫土豆, 該死的誰踢我...
魔法方法:__init__(self)
__init__(self, parma1, parma2, ...)
舉例:
>>> class Ball:
def __init__(self, name):
self.name = name
def kick(self):
print('我叫%s,該死的,誰踢我!!' % self.name)
>>> b = Ball('土豆')
>>> b.kick()
我叫土豆,該死的,誰踢我!!
>>> a = Ball() ?#__init__默認設(shè)置了name,所以必須傳遞name實參,否則報錯
TypeError: __init__() missing 1 required positional argument: 'name'
公有和私有
name mangling 名字改變/名字重造
公有成員:默認創(chuàng)建的成員均為公有。
私有成員:
(1) 在變量或函數(shù)名前加上"_"兩個下劃線即可。
(2) python中類的私有均屬于偽私有,通過"對象._類_變量"的形式可以訪問私有成員
舉例:
>>> 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中類的私有屬于偽私有,此方式可訪問私有成員
'yuan.jiang'
繼承 inherit
class DerivedClassName(BaseClassName):
...
(1) 如果子類中定義于父類同名的成員時,則會自動覆蓋父類對應(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): ?#重寫了__init__方法覆蓋了父類的__init__子類無法調(diào)用到self.x和self.y屬性成員,導(dǎo)致了子類無法訪問到父類的屬性或方法的問題
? ? ? ? self.hungry = True
? ? def eat(self):
? ? ? ? if self.hungry:
? ? ? ? ? ? print('吃貨的夢想就是天天有的吃^_^')
? ? ? ? ? ? self.hungry = False
? ? ? ? else:
? ? ? ? ? ? print('太撐了,吃不下了!')
運行:
>>> fish = Fish()
>>> fish.move()
我的位置是: 3 0
>>> fish.move()
我的位置是: 2 0
>>> goldfish = Goldfish()
>>> goldfish.move()
我的位置是: 4 9
>>> goldfish.move()
我的位置是: 3 9
>>> shark = Sharkfish()
>>> shark.eat()
吃貨的夢想就是天天有的吃^_^
>>> shark.eat()
太撐了,吃不下了!
>>> shark.move() ?#無法訪問到父類的__init__()方法中的x變量
AttributeError: 'Sharkfish' object has no attribute 'x'
--------------------------------2017.09.02----------------------------------------
覆蓋屬性或方法問題優(yōu)化
問題:針對子類屬性或方法覆蓋父類屬性或方法的情況,導(dǎo)致子類無法訪問父類中被覆蓋的屬性
(1) 調(diào)用未綁定的父類的方法
(2) 使用super方法(推薦)
舉例:
def __init__(self):
Fish.__init__(self) ?#調(diào)用未綁定的父類的方法,相當(dāng)于>>>Fish.__init__(Sharkfish)
self.hungry = True
運行:
>>> shark = Sharkfish()
>>> shark.move()
我的位置是: -1 2
>>> shark.move()
我的位置是: -2 2
舉例:
def __init__(self):
super().__init__() ?#使用super方法解決
self.hungry = True
運行:
>>> shark = Sharkfish()
>>> shark.move()
我的位置是: 8 3
>>> shark.move()
我的位置是: 7 3
多重繼承
class DerivedClassName(Base1, Base2, Base3, ...):
...
#建議少用,有可能會導(dǎo)致不可預(yù)見的bug(不可預(yù)見最麻煩)
>>> 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 只,小魚 %d 條!' % (self.turtle.num, self.fish.num))
運行:
>>> pool = Pool(1, 10)
>>> pool.print_num()
水池里總共有烏龜 1 只,小魚 10 條!
類、類對象、示例對象
類定義 ? ?C
類對象 ? ?C
實例對象 ?a ?b ?c
舉例:
>>> class C: ? #C, 既是類,也是類對象
count = 0
>>> a = C() ? ?#a,實例對象
>>> b = C() ? ?#b,實例對象
>>> c = C() ? ?#c,實例對象
>>> a.count
0
>>> b.count
0
>>> c.count
0
>>> c.count += 10
>>> c.count
10
>>> a.count
0
>>> b.count
0
>>> C.count ? ?#C,作為類對象
0
>>> C.count += 100 ? ?#C,作為類對象
>>> a.count
100
>>> b.count
100
>>> c.count
10
(1) 當(dāng)屬性名與方法名沖突,會導(dǎo)致方法不能正常調(diào)用。
(2) 一般遵循規(guī)則:屬性名用英文名詞,方法名用英文動詞。
(3) python嚴格要求方法需要有實例才能被調(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)用出錯
TypeError: 'int' object is not callable
>>> class BB:
def printBB():
print('no zuo no die.')
>>> BB.printBB()
no zuo no die.
>>> #沒有self,也沒有將類實例化
>>> 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>}) ?#使用類對象顯示類的屬性詳情
>>> dd.setXY(4, 5)
>>> dd.__dict__
{'y': 5, 'x': 4} ?#將實例對象dd使用類的屬性詳情實例化了
>>> # 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)的,類的實例對象中也會靜態(tài)存儲,所以實例對象dd正常存在。
類與對象的內(nèi)置函數(shù)
issubclass
功能:測試一個類是否是另外一個類的子類
issubclass(class, classinfo)
(1) 一個類被認為是其自身的子類
(2) classinfo可以是類對象的元組,只要class屬于其中任何一個候選類的子類,則返回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
功能:測試一個對象是否是一個類的實例對象
isinstance(object, classinfo)
(1) object為類的實例對象,如果不是類的實例對象,永遠返回False
(2) 如果第二個參數(shù)不是類或者由類對象組成的元組,會拋出一個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對象是否在A/B/C里面,答案是True
True
hasattr
功能:測試一個對象里面是否有指定的屬性
hasattr(object, name)
(1) object 對象名, name 是屬性名(需要用引號引起來,否則報錯)
getattr
功能:返回對象指定的屬性值
getattr(object, name[, default])
(1) 如果屬性值不存在打印default,沒有default則拋出異常
setattr
功能:設(shè)置對象中指定屬性的值,如果屬性不存在則創(chuàng)建并賦值
setattr(object, name, value)
delattr
功能:刪除對象中指定的屬性,如果屬性不存在則拋出異常
delattr(object, name)
舉例:
>>> class C:
def __init__(self, x=0):
self.x = x
>>> c1 = C()
>>> hasattr(c1, 'x') ?#測試對象屬性是否存在
True
>>> hasattr(c1, x)\
NameError: name 'x' is not defined
>>> getattr(c1, 'x') ?#獲取對象屬性的值
0
>>> getattr(c1, 'y')
AttributeError: 'C' object has no attribute 'y'
>>> getattr(c1, 'y', '您所訪問的屬性不存在!') ?#設(shè)置default默認提示語
'您所訪問的屬性不存在!'
>>> setattr(c1, 'y', 100) ?#設(shè)置對象屬性的值
>>> getattr(c1, 'y')
100
>>> delattr(c1, 'y') ?#刪除對象屬性的值
>>> delattr(c1, 'y')
Traceback (most recent call last):
? File "<pyshell#264>", line 1, in <module>
? ? delattr(c1, 'y')
AttributeError: y
property
功能:設(shè)置一個定義好的屬性,通過對象屬性來設(shè)置對象屬性
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)系,刪除其中一個另一個即不能訪問
AttributeError: 'C' object has no attribute 'size'
20丶魔法方法 magic methods
(1) 魔法方法總是被雙下劃綫包圍,如 __init__
(2) 魔法方法是面向?qū)ο蟮膒ython的一切
(3) 魔法方法的魔力體現(xiàn)在能夠在適當(dāng)?shù)臅r候被調(diào)用
魔法方法匯總:http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
__init__(self[, ...])
功能:初始化類對象(根據(jù)需求決定是否增加屬性參數(shù))
返回值: None
舉例:
>>> class Rectangle: #矩形類,需要長和寬,所以重寫__init__
def __init__(self, x, y):
self.x = x
self.y = y
def getPeri(self): ?#獲得周長
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)建一個類對象
返回值:返回一個對象
(1) 在__init__方法之前被調(diào)用,屬于類創(chuàng)建時第一個被調(diào)用的方法
舉例:
>>> class CapStr(str): ?#繼承一個不可改變的類型str
def __new__(cls, string): ?#使用new將類型的功能進行轉(zhuǎn)換
string = string.upper()
return str.__new__(cls, string) ?#把重寫后的str中的new方法帶傳代餐返回
>>> a = CapStr("I love M.")
>>> a
'I LOVE M.'
__del__(self)
功能:對象將要被銷毀的時候,自動調(diào)用,屬于自動垃圾回收方法
注意: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 ?#對象的賦值不會調(diào)用__init__
>>> c3 = c2
>>> del c3
>>> del c2
>>> del c1 ? #其他的賦值對象del時不會調(diào)用__del__ (c2和c3只是c1的一份拷貝)
我是del方法,我被調(diào)用了!
算術(shù)運算魔法方法
__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)用時的行為
__pow__(self, other[, modulo]) power()調(diào)用或 ** 運算時的行為
__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
類定制的計時器
(1) 定制一個計時器的類
(2) start和stop方法代表啟動計時和停止計時
(3) 假設(shè)計時器對象t1,print(t1)和直接調(diào)用t1均顯示結(jié)果
(4) 當(dāng)計時器未啟動或已經(jīng)停止計時,調(diào)用stop方法會給與溫馨的提示
(5) 兩個計時器對象可以進行相加:t1 + t2
需要的資源:
(1) 使用time模塊的localtime方法獲取時間
(2) __str__ 方法 __repr__ 方法可用來打印文字
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)
類定制計時器代碼:http://blog.csdn.net/sinat_36184075/article/details/77806778
屬性訪問
__getattribute__(self, name) #定義當(dāng)該類的屬性被訪問時的行為
__getattr__(self, name) #定義當(dāng)用戶試圖獲取一個不存在的屬性時的行為
__setattr__(self, name, value) #定義當(dāng)一個屬性被設(shè)置(包括初始化)時的行為
__delattr__(self, name) #定義一個屬性被刪除時的行為
舉例:
>>> 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 ?#初始化時自動調(diào)用setattr
>>> c.x
getattribute
1
>>> del c.x
delattr
舉例:屬性訪問時的嚴重問題,無限遞歸
class Rectangle: ?#矩形
? ? def __init__(self, width=0, height=0): ?#寬高不相等,長方形
? ? ? ? self.width = width
? ? ? ? self.height = height
? ? def __setattr__(self, name, value):
? ? ? ? if name == 'square': ?#寬高相等,正方形
? ? ? ? ? ? self.width = value
? ? ? ? ? ? self.height = value
? ? ? ? else:
? ? ? ? ? ? #self.name = value ? #會導(dǎo)致類無限遞歸自己
? ? ? ? ? ? super().__setattr__(name, value) ?#解決辦法①:super() 推薦。
? ? ? ? ? ? #self.__dict__[name] = value ? ? ?#解決辦法②:字典
? ? def getArea(self):
? ? ? ? return self.width * self.height
運行:
>>> 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
描述符就是將某種特殊類型的類的實例指派給另一個類的屬性。
__get__(self, instance, owner) ?#用于訪問屬性,返回屬性的值
__set__(self, instance, value) ?#將在屬性分配操作中調(diào)用,不反悔任何內(nèi)容
__delete__(self, instance) ? ?#控制刪除操作,不返回任何內(nèi)容
@self, 描述符類本身的類實例
@instance, 擁有者的類實例
@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() ? #實例化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擁有者的實例對象
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)換
定義一個溫度類,然后定義兩個描述符類用于描述攝氏度和華氏度兩個屬性。
要求兩個屬性會自動進行轉(zhuǎn)換,也就是說可以給攝氏度這個屬性賦值,打印華氏度是自動轉(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在實例對象中被賦值時調(diào)用對應(yīng)類的__set__
運行:
>>> 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í):
編寫一個不可改變的自定義列表,要求記錄列表中每個元素被訪問的次數(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]
運行:
>>> c1 = CountList(1, 3, 5, 7, 9)
>>> c2 = CountList(2, 4, 6, 7, 10)
>>> c1[1] ?#c1[1] == 3被訪問1次
3
>>> c2[1]
4
>>> c1[1] + c2[1] ?#c1[1] == 3被訪問2次
7
>>> c1.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c1[1] ?#c1[1] == 3被訪問3次
3
>>> c1.count
{0: 0, 1: 3, 2: 0, 3: 0, 4: 0}
迭代器 iter-next
iter
iter() 內(nèi)置方法, 功能:返回一個迭代器對象
__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 u a n . j i a n g?
斐波那契數(shù)列迭代器
>>> class Fibs: ?#斐波那契數(shù)列
def __init__(self, n=10): ? ?#加一個參數(shù)n控制迭代范圍
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self ?#本身就是一個迭代器
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é)同程序:可以運行的對立函數(shù)調(diào)用,函數(shù)可以暫停或掛起,并再需要的時候從程序離開的地方繼續(xù)活著重新開始。
舉例:
>>> 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)自動檢測迭代器的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}
#沒有字符串推導(dǎo)式,引號內(nèi)的強制解釋為字符串
>>> e = (i for i in range(10)) ?#沒有元組推導(dǎ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
生成器擴展閱讀:
http://bbs.fishc.com/forum.php?mod=viewthread&tid=56023&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
21丶模塊 module
容器 -> 數(shù)據(jù)的封裝
函數(shù) -> 語句的封裝
類 ? -> 方法和屬性的封裝
模塊 -> 程序的封裝,其實就是.py的python程序
(1) import導(dǎo)入的.py模塊文件必須放在與python.exe同一目錄下,即可正確導(dǎo)入。
(2) 導(dǎo)入方法有三種:
① import 模塊名
② from 模塊名 import 函數(shù)名1, 函數(shù)名2, ... ?#不建議這樣用,可能會覆蓋系統(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))
運行calc.py:
=================== RESTART: C:\python\test_module\calc.py ===================
32攝氏度 = 89.6華氏度
99華氏度 = 37.2攝氏度
>>>?
__name__
if __name__ = '__main__': ?#決定是.py文件中的代碼是當(dāng)前程序運行,還是導(dǎo)入到其他程序中作為模塊使用而運行
作用:限制為自身.py程序運行才執(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進去
>>> 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)建一個文件夾,用于存放相關(guān)的模塊,文件夾的名字即包(package)的名字
(2) 在文件夾中創(chuàng)建一個 __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運行時將其解釋為包
#calc.py中修改為:包名.模塊名
import M1.TemperatureConversion as tc
print('32攝氏度 = %.1f華氏度' % tc.c2f(32))
print('99華氏度 = %.1f攝氏度' % tc.f2c(99))
自帶電池:python標準庫
(1) 電池:python-IDLE 幫助文檔 F1
(2) 來自全球開發(fā)者貢獻的python模塊:https://pypi.python.org/pypi
#也可以自己寫模塊發(fā)布上去。
(3) PEP:python增強建議書,規(guī)范與定義python各種加強和延伸功能的技術(shù)規(guī)格,即參考標準
(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實例:網(wǎng)絡(luò)爬蟲
python訪問網(wǎng)絡(luò): urllib (是個包模塊)
URL一般格式:
protocol://hostname[:port]/path/[;parameters][?query]#fragment
URL三部分組成:
(1) 協(xié)議:http, https, ftp, file, ed2k...
(2) 域名/IP地址:如http默認端口號80
(3) 資源具體地址:如目錄或文件名
查看幫助文檔后發(fā)現(xiàn)urllib包有4個模塊:
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' ?#整個網(wǎng)頁的二進制文件以16進制顯示
>>> html = html.decode('utf-8') ?#按其編碼方式解碼
>>> print(html)
"""
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
</body>
</html>
"""
訪問網(wǎng)頁內(nèi)容存儲本地
舉例:
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)
運行:
會生成這個文件:C:\Users\Jan\Desktop\python_study\cat_1920_1080.jpg
實現(xiàn)POST請求 - 自動翻譯機
import urllib.request as url_req
import urllib.parse ? as url_prs
import json ?#json, 輕量級的數(shù)據(jù)交換格式
while True:
? ? content = input('請輸入需要翻譯的內(nèi)容<.q退出>:')
? ? if content == '.q':
? ? ? ? break
? ? else:
? ? ? ? #注意url地址<有道翻譯>,按小甲魚視頻中的可能不對,需到網(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']))
#缺陷:能夠被識別為代碼訪問,而非瀏覽器,即非人類訪問
運行:
========= RESTART: C:\Users\Jan\Desktop\python_study\translation.py =========
請輸入需要翻譯的內(nèi)容<.q退出>:生存,還是毀滅,這是一個問題
翻譯結(jié)果:To survive, or not to be, this is a problem
請輸入需要翻譯的內(nèi)容<.q退出>:To be or not to be, it's a question.
翻譯結(jié)果:生存還是毀滅,這是一個問題。
請輸入需要翻譯的內(nèi)容<.q退出>:.q
>>>?
修改header
(1) 通過Request的headers參數(shù)修改,字典形式
(2) 通過Request.add_header()方法修改
追加header模擬瀏覽器訪問:
import urllib.request as url_req
import urllib.parse ? as url_prs
import json ?#json, 輕量級的數(shù)據(jù)交換格式
while True:
? ? content = input('請輸入需要翻譯的內(nèi)容<.q退出>:')
? ? if content == '.q':
? ? ? ? break
? ? else:
? ? ? ? #注意url地址,視頻中的可能不對需到網(wǎng)上查
? ? ? ? url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http://www.youdao.com/'
? ? ? ? #header方法1:創(chuàng)建字典,請求中傳參
? ? ? ? '''
? ? ? ? head = {} ?#模擬瀏覽器訪問 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)用請求的方法:data, head '''
? ? ? ? #header方法2:請求中追加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']))
運行:
========= RESTART: C:\Users\Jan\Desktop\python_study\translation.py =========
請輸入需要翻譯的內(nèi)容<.q退出>:生存,還是毀滅,這是一個問題
翻譯結(jié)果:To survive, or not to be, this is a problem
請輸入需要翻譯的內(nèi)容<.q退出>:To be or not to be, it's a question.
翻譯結(jié)果:生存還是毀滅,這是一個問題。
請輸入需要翻譯的內(nèi)容<.q退出>:.q
>>>?
代理
作用:讓爬蟲偽裝瀏覽器請求,讓http服務(wù)器不會認為是非人類訪問。
步驟:
(1) 參數(shù)是一個字典{'類型':'代理ip:端口號'}
proxy_support = urllib.request.ProxyHandler({})
(2) 定制、創(chuàng)建一個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' ?#這個網(wǎng)站訪問它會顯示自己的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隨機取ip
#網(wǎng)上查的免費代理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)
補充:
Beautiful Soup 是用Python寫的一個HTML/XML的解析器,使用安裝python-IDLE時附帶的pip命令,直接在windows下執(zhí)行:
C:\python> pip install bs4
#一鍵安裝搞定,python中測試能否導(dǎo)入成功
>>> from bs4 import BeautifulSoup
>>> #成功導(dǎo)入,失敗會報異常。
采集代理ip
import urllib.request as url_req
from bs4 import BeautifulSoup ?#此庫需要安裝:win-cmd執(zhí)行"pip install bs4"即可
import random
import pprint as ppr
#這個網(wǎng)站訪問它會顯示自己的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頁
? ? ? ? ? ? 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()搜索解析器解析出來的html文檔樹
? ? ? ? ? ? for x in range(1, len(ips)):
? ? ? ? ? ? ? ? ip = ips[x]
? ? ? ? ? ? ? ? tds = ip.findAll('td') ?#ip和端口都在tr標簽中的td標簽中
? ? ? ? ? ? ? ? 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}) ?#從列表中隨機選擇代理ip和端口項
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)
運行:
======== 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>真實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) #打開一個鏈接,參數(shù)可以是一個字符串或者Request對象
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爬蟲下載妹子圖
代碼:#代理ip不太穩(wěn)定,免費代理很多時好時壞
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
#打開url接口函數(shù)
def url_open(url):
? ? req = urllib.request.Request(url)
? ? req.add_header(header_key, header_value)
? ? '''
? ? #使用代理模擬真人訪問而不是代碼訪問
? ? 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位置開始找到一個]符號
? ? 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位置開始,以 .jpg 結(jié)尾的地方
? ? ? ? if b != -1: ?#find找不到時返回-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開始
? ? #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取最后一個元素
? ? ? ? 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/' ?#實際圖源來源于新浪服務(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----------------------------------------
正則表達式
"我知道,可以使用正則表達式解決現(xiàn)在遇到的難題。"于是,現(xiàn)在他就有兩個問題了。
>>> import re
>>> re.search(r'Hello', 'I love you, Hello!~') ?#search()方法用于在字符串中搜索正則表達式模式第一次出現(xiàn)的位置
<_sre.SRE_Match object; span=(12, 17), match='Hello'> ?#第12-16個字符位置
>>> re.search(r'lo', 'hello')
<_sre.SRE_Match object; span=(3, 5), match='lo'>
>>> 'hello'.find('lo')
3
#.點號:匹配除了換行符的任何字符
>>> re.search(r'.', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(0, 1), match='I'>
#匹配點號本身,使用\反斜杠轉(zhuǎn)義即可
>>> re.search(r'\.', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(17, 18), match='.'>
#\d表示匹配一個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') #無法匹配,位數(shù)不同
#使用[]創(chuàng)建一個字符類
>>> 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'>
#{}大括號:來限定匹配的次數(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') ?#錯誤示范
>>> re.search(r'[0-255]', '188') ?#0,1,2,5其中任何一個,匹配
<_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正則表達式
<_sre.SRE_Match object; span=(0, 3), match='188'>
#ip地址正則表達式
>>> 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表達式的一點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地址匹配的正則表達式【嚴謹版】
import re
ptnIP = re.compile(r'(?<![\d.])' # 前導(dǎo) 無 數(shù)字和小數(shù)點
? ? ? ? ? ? ? ? ? ?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ù) 無 數(shù)字和小數(shù)點
? ? ? ? ? ? ? ? ? )
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)
運行:
========== 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 正則表達式特殊符號及用法(詳細列表)
http://blog.csdn.net/riba2534/article/details/54288552
正則表達式舉例:
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)' ?# 正則表達式匹配貼吧圖片鏈接
? ? imglist = re.findall(p, html) ?# findall中的p包含子組()的話,會單獨返回子組
? ? # 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))
運行:
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) 無 數(shù)字和小數(shù)點
? ? ? ? ? ? ?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ù) 無 數(shù)字和小數(shù)點
? ? iplist = re.findall(ptnIP, html) ?# findall中的p包含子組()的話,會單獨返回子組
? ? # 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') ?#打開一個不存在的鏈接
>>> try:
urllib.request.urlopen(req)
except urllib.error.URLError as e:
print(e.reason)
[Errno 11001] getaddrinfo failed ?#錯誤信息
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'
處理異常的寫法:
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爬蟲框架
① Scrapy的安裝與環(huán)境搭建
Scrapy對應(yīng)python2.7的版本。(安裝過程中如遇任何問題均可百度搜索一下,這是程序員必須學(xué)會的快速解決問題的辦法)
1. 安裝python2.7(32位版本)
安裝包:python-2.7.6-win32.msi
設(shè)置環(huán)境變量:win-運行-cmd
> C:\Python27\python.exe C:\Python27\tools\Scripts\win_add2path.py
重啟windows系統(tǒng),驗證安裝是否成功:
> python --version
#如果顯示是3.多的版本,請參考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),驗證安裝是否成功:
> pip --version
#如果沒有顯示版本信息,請參考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
驗證是否安裝成功:
> Scrapy
#如果提示找不到命令的話,可能需要一個工具環(huán)境支持:Twisted-15.0.0.win32-py2.7.msi
安裝完Twisted后再次嘗試驗證即可。
② Scrapy框架爬蟲程序初探
一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。最初是為了頁面抓取所設(shè)計的,也可以應(yīng)用在獲取API所訪問的數(shù)據(jù)上,或者說通用的網(wǎng)絡(luò)爬蟲上。
使用Scrapy抓取一個網(wǎng)站一共需要四個步驟:
1. 創(chuàng)建一個Scrapy項目;
2. 定義Item容器;
3. 編寫爬蟲;
4. 存儲內(nèi)容。
---Scrapy框架(官網(wǎng))圖示---
實驗網(wǎng)站對象:www.dmoz.org
1. 創(chuàng)建一個Scrapy項目:crawler
C:\Users\Jan\Desktop\python_study>Scrapy startproject crawler
#crawler是我們的項目名稱
在\python_study\crawler\文件夾中即是我們的爬蟲框架。
Item是保存爬取到的數(shù)據(jù)的容器,其使用方法和python字典類似,并且提供了額外保護機制來避免拼寫錯誤導(dǎo)致的未定義字段錯誤。
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. 編寫爬蟲:
編寫爬蟲類Spider,Spider是用戶編寫用于從網(wǎng)站上爬取數(shù)據(jù)的類。其包含了一個用于下載的初始化URL,然后是如何跟進網(wǎng)頁中的鏈接以及如何分析頁面中的內(nèi)容,還有提取生成item的方法。
#crawler\crawler\spiders\crawler_spider.py 新建文件
import scrapy
class CrawlerSpider(scrapy.Spider):
? ? name = 'csdn' ?#爬蟲名字,調(diào)用的時候使用
? ? 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爬蟲類中的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: 我們的目標爬取鏈接
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)容存儲位置(爬取網(wǎng)站的源碼文件):
C:\Users\Jan\Desktop\python_study\crawler\ 目錄下 geek.csdn.net 的NET文件。
3.2 取
在Scrapy中使用的是一種基于XPath和CSS的表達式機制:Scrapy Selectors(選擇器)
Selector是一個選擇器,有4個基本方法:
xpath() 傳入xpath表達式,返回該表達式所對應(yīng)的所有節(jié)點的selector list列表。
css() 傳入CSS表達式,返回該表達式所對應(yīng)的所有節(jié)點的selector list列表。
extract() 序列化該節(jié)點為unicode字符串并返回list。
re() 根據(jù)傳入的正則表達式對數(shù)據(jù)進行提取,返回unicode字符串list列表。
win-cmd進入項目根目錄后執(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)頁的源碼信息
>>> response.headers ?#輸出網(wǎng)頁的頭部信息
{'Date': ['Fri, 08 Sep 2017 14:06:31 GMT'], 'Content-Type': ['text/html; charset=utf-8'], 'Server': ['openresty'], 'Vary': ['Accept-Encoding', 'Accept-Encoding']}
XPath是一門在網(wǎng)頁中查找特定信息的語言,所以用XPath來篩選數(shù)據(jù),要比使用正則表達式容易些。
/html/head/title 選擇HTML文檔中<head>標簽內(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>標簽的內(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>標簽中的字符串,即標題
>>> sel.xpath('//span/a/@href').extract() ?#獲取<span><a>中的連接地址
>>> sites = sel.xpath('//div/div/div/dl/dd/span/a/text()').extract() ?#按照標簽包裹的層級<body>下開始找到包裹標題的<a>標簽寫入xpath中
>>> for title in sites: ?#使用for循環(huán)打印可以自動將Unicode轉(zhuǎn)換為對應(yīng)中文編碼顯示
... ? ? print(title)
自己動手做聊天機器人 四十二-(重量級長文)從理論到實踐開發(fā)自己的聊天機器人
微軟攜手 Facebook 推出開源項目 打造共享神經(jīng)網(wǎng)絡(luò)模型
Taylor Swift vs 人工智能:作詞誰更強?
推薦13個機器學(xué)習(xí)框架
...
>>> sites = sel.xpath('//div/div/div[@class="directory-url"]/dl/dd/span/a/text()').extract()
#其中[@class="directory-url"]的功能是:過濾掉對應(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
#運行就可以將print中的內(nèi)容在爬取時一并顯示出來(輸出內(nèi)容略)
4. 存儲內(nèi)容
最常見的導(dǎo)出為json格式。
中文亂碼問題:http://bbs.fishc.com/thread-85672-1-1.html
#crawler\crawler\spiders\crawler_spider.py ?構(gòu)造items的列表對象
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() ?#實例化一個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)容存儲的文件名以及校正中文亂碼
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' ?#這一句會將你每次返回的字典抓取出來,“ensure_ascii=False”這一句話很重要,如果是True的話就是我們保存的\u4e2d\u56fd這種格式了
? ? ? ? self.file.write(line) ?#寫入到文件中
? ? ? ? return item
#crawler\crawler\setting.py ?使pipelines.py生效,取消注釋ITEM_PIPELINES
ITEM_PIPELINES = {
? ? 'crawler.pipelines.CrawlerPipeline': 300, ?#300是正常值,不變。
}
win-cmd運行scrapy,即可自動在\crawler\目錄下生成items.json文件,并且中文顯示正常:
C:\Users\Jan\Desktop\python_study\crawler>scrapy crawl csdn
C:\Users\Jan\Desktop\python_study\crawler\items.json ?#中文正常。
{"title": ["自己動手做聊天機器人 四十二-(重量級長文)從理論到實踐開發(fā)自己的聊天機器人"], "link": ["http://www.shareditor.com/blogshow?blogId=136&hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
{"title": ["微軟攜手 Facebook 推出開源項目 打造共享神經(jīng)網(wǎng)絡(luò)模型"], "link": ["http://tech.163.com/17/0908/08/CTQ1403R00097U80.html"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
{"title": ["Taylor Swift vs 人工智能:作詞誰更強?"], "link": ["http://dataquestion.com/taylor-vs-ai"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
...
--------------------------------2017.09.09----------------------------------------
23丶GUI界面的終極選擇 Tkinter
Tkinter是python的默認GUI模塊庫。
示例1:主窗口及標題
import tkinter as tk
app = tk.Tk() ?#根窗口的實例(root窗口)
app.title('Tkinter root window') ?#根窗口標題
theLabel = tk.Label(app, text='我的第2個窗口程序!') ?#label組件及文字內(nèi)容
theLabel.pack() ?#pack()用于自動調(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('臥槽,居然打了個招呼!~')
root = tk.Tk()
app = APP(root)
root.mainloop()
示例3:圖片
from tkinter import *
root = Tk()
textLabel = Label(root,
? ? ? ? ? ? ? ? ? text='請重試!\n您的操作不被允許!', ?#文字支持換行
? ? ? ? ? ? ? ? ? justify=LEFT, ?#左對齊
? ? ? ? ? ? ? ? ? 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這是一個問題',
? ? ? ? ? ? ? ? ?justify=LEFT,
? ? ? ? ? ? ? ? ?image=photo,
? ? ? ? ? ? ? ? ?compound=CENTER,
? ? ? ? ? ? ? ? ?font=('華文隸書', 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('請重試!\n您的操作不被允許!')
textLabel = Label(frame1,
? ? ? ? ? ? ? ? ? textvariable=var,
? ? ? ? ? ? ? ? ? justify=LEFT) ?#左對齊
textLabel.pack(side=LEFT)
#顯示圖片
photo = PhotoImage(file='tk_image.png')
imageLabel = Label(root, image=photo)
imageLabel.pack(side=RIGHT)
theButton = Button(frame2, text='我是超級管理員', command=callback)
theButton.pack()
frame1.pack(padx=10, pady=10)
frame2.pack(padx=10, pady=10)
mainloop()
示例6:選項按鈕
from tkinter import *
root = Tk()
v = IntVar()
c = Checkbutton(root, text='測試一下', variable=v) ?#v用來存放選中狀態(tài)
c.pack()
l = Label(root, textvariable=v)
l.pack() ?#未選中顯示為0,選中顯示1
mainloop()
示例7:多個方框選項
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è)置對齊方位,東E南S西W北N
mainloop()
示例8:多個圓點選項 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)陷填充按鈕選項 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: ?#對應(yīng)列表中包含元組同時執(zhí)行多個循環(huán)
? ? b = Radiobutton(root, text=lang, variable=v, value=num, indicatoron=False)
? ? b.pack(fill=X)
mainloop()
示例10:附帶標題的圓點選項 LabelFrame
from tkinter import *
root = Tk()
group = LabelFrame(root, text='最好的開發(fā)語言是?', 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: ?#對應(yīng)列表中包含元組同時執(zhí)行多個循環(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, '默認文本...')
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)容時點擊獲取信息會打印
? ? 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='點擊退出', width=10, command=root.quit) \
? ? ? ? ? ? ?.grid(row=3, column=1, sticky=E, padx=10, pady=5)
#退出按鈕必須是雙擊打開.py文件才可以,而不是在IDLE下調(diào)試運行時
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)
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('賬號:%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='點擊退出', width=10, command=root.quit) \
? ? ? ? ? ? ?.grid(row=3, column=1, sticky=E, padx=10, pady=5)
#退出按鈕必須是雙擊打開.py文件才可以,而不是在IDLE下調(diào)試運行時
mainloop()
示例13:輸入對錯驗證程序
from tkinter import *
root = Tk()
root.title('輸入對錯驗證')
def test():
? ? if e1.get() == '張三':
? ? ? ? print('正確!')
? ? ? ? return True
? ? else:
? ? ? ? print('錯誤!')
? ? ? ? e1.delete(0, END)
? ? ? ? return False
v = StringVar()
#focusout指定在當(dāng)前輸入框失去焦點時,代表輸入完,會去調(diào)用test校驗<tab>鍵可測試
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:簡單計算器程序
from tkinter import *
root = Tk()
root.title('計算器程序')
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ào)用test校驗<tab>鍵可測試
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='計算結(jié)果', command=calc).grid(row=1, column=2, pady=5)
mainloop()
示例14:按鈕刪除列表中的選項
from tkinter import *
master= Tk()
theLB = Listbox(master, selectmode=SINGLE, height=15) ?#SINGLE單選,MULTIPLE多選,height設(shè)置顯示項數(shù)
theLB.pack()
for item in ['筆', '墨', '紙', '硯']:
? ? theLB.insert(END, item) ?#END表示最后一個
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:為列表組件添加滾動條
安裝垂直滾動條步驟:
1) 設(shè)置該組件的yscrollbarcommand選項為Scrollbar組件的set方法;
2) 設(shè)置Scrollbar組件的command選項為該組件的yview()方法。
from tkinter import *
root = Tk()
root.title('滾動條程序')
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)
#讓滾動條與選項互通互連
sb.config(command=lb.yview)
mainloop()
示例16:滑塊滾動條 Scale
from tkinter import *
root = Tk()
root.title('滑塊程序')
s1 = Scale(root, from_=0, to=100, tickinterval=5, resolution=5, length=200) ?#默認是垂直, 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)前位置,點擊后才有效
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表示輸入光標插入的位置
text.insert(END, '對比一下效果。')
def show():
? ? print('提交中...') ?#此行內(nèi)容顯示在IDLE中
#插入一個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)
#插入一個圖片
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') ?#文字會以red為準
mainloop()
示例20:文本組件中可點擊連接
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>鼠標進入
text.tag_bind('link', '<Leave>', show_xterm_cursor) ?#<Enter>鼠標離開
text.tag_bind('link', '<Button-1>', click) ?#<Enter>鼠標點擊
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('無任何修改!')
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' ?#開頭的位置,第1行的第0個下標位置
while True:
? ? pos = text.search('o', start, stopindex=END) ?#查找文本中字符o的位置
? ? if not pos:
? ? ? ? break
? ? print('找到啦,位置是:', getIndex(text, pos))
? ? start = pos + '+1c' ?#'+1c'指向下一個字符
mainloop()
示例23:文本組件之撤銷操作
from tkinter import *
root = Tk()
root.title('link click')
text = Text(root, width=50, height=10, undo=True) ?#undo模式開啟
text.pack()
text.insert(INSERT, 'I love www.baidu.com')
def show():
? ? text.edit_undo()
Button(root, text='撤銷', command=show).pack() ?#多次撤銷會刪除文本組件內(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')
#藍色的豎虛線
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) ?#移動位置
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') ?#橢圓是通過限定矩形的方式畫出來,圓形通過正方形
#w.create_oval(60, 30, 300, 270, fill='pink') ?#正方形對應(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 = [
? ? #左上點
? ? center_x - int(r * m.sin(2 * m.pi / 5)),
? ? center_y - int(r * m.cos(2 * m.pi / 5)),
? ? #右上點
? ? center_x + int(r * m.sin(2 * m.pi / 5)),
? ? center_y - int(r * m.cos(2 * m.pi / 5)),
? ? #左下點
? ? center_x - int(r * m.sin(m.pi / 5)),
? ? center_y + int(r * m.cos(m.pi / 5)),
? ? #頂點
? ? center_x,
? ? center_y - r,
? ? #右下點
? ? 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 (自定義畫板)
#繪制一個極小的圓來代表一個點(tkinter本身不支持畫點)
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>綁定鼠標左鍵事件
Label(root, text='按住鼠標左鍵并移動,開始繪制吧!~~').pack(side=BOTTOM)
mainloop()
示例30:菜單組件 Menu (主菜單/下拉菜單/右鍵菜單/單多選菜單/按鈕菜單/選項菜單(列表))
from tkinter import *
root = Tk()
root.title('Main Menu Show')
def callback():
? ? print('你好~')
menubar = Menu(root)
#注冊菜單:文件(下拉菜單)
filemenu = Menu(menubar, tearoff=False) ?#來自主菜單,tearoff參數(shù)可讓菜單窗口分離
filemenu.add_command(label='新建', command=callback)
filemenu.add_command(label='打開...', 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) ?#來自主菜單
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='多選項1', command=callback, variable=openVar)
optionmenu.add_checkbutton(label='多選項2', command=callback, variable=saveVar)
optionmenu.add_checkbutton(label='多選項3', command=callback, variable=quitVar)
menubar.add_cascade(label='選項(C)', menu=optionmenu)
#主菜單:單選√ radiobutton(下拉菜單)
otherVar = IntVar()
othermenu = Menu(menubar, tearoff=False)
othermenu.add_radiobutton(label='單選項1', command=callback, variable=otherVar, value=1)
othermenu.add_radiobutton(label='單選項2', command=callback, variable=otherVar, value=2)
othermenu.add_radiobutton(label='單選項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)部菜單:選項菜單 OptionMenu
variable = StringVar()
variable.set('one') ?#默認顯示one
w = OptionMenu(root, variable, 'one', 'two', 'three')
w.pack()
#將列表添加到選項菜單 OptionMenu
OPTIONS = [
? ? '表項1',
? ? '對比2',
? ? '選項3',
? ? '其他4',
? ? '退出5'
? ? ]
var = StringVar()
var.set(OPTIONS[0])
o = OptionMenu(root, var, *OPTIONS) ?#*星號解包可變參數(shù)列表為逐個元素
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為鼠標右鍵,1為左鍵,2為中鍵
root.config(menu=menubar) ?#menu參數(shù)會將菜單設(shè)置添加到root根窗口
mainloop()
示例31:事件綁定 bind (鼠標/按鍵/按鍵組合)
from tkinter import *
root = Tk()
root.title('Event bind')
frame = Frame(root, width=200, height=200)
#鼠標響應(yīng)事件
def callback1(event): ?#event形參獲取事件描述,必備參數(shù)
? ? print('點擊位置:', event.x, event.y)
frame.bind('<Button-1>', callback1) ?#Button表示鼠標點擊事件, 12345分別代表左中右鍵上滾下滾
frame.pack()
#鍵盤響應(yīng)事件
def callback2(event):
? ? print(event.keysym) ?#打印信息在IDLE, keysym指鍵盤所有按鍵
frame.bind('<Key>', callback2)
frame.focus_set()
frame.pack()
#鼠標即時響應(yīng)事件
def callback3(event):
? ? print('點擊位置:', event.x, event.y)
frame.bind('<Motion>', callback3) ?#鼠標在窗口內(nèi)只要有移動就一直輸出位置
frame.pack()
#事件序列(按鍵組合),語法:<modifier-type-detail> 如
#點擊鼠標左鍵:<Button-1> ?ButtonRelease更安全,移除組件釋放點擊時不去觸發(fā)
#點擊H字母按鍵:<KeyPress-H>
#同時點擊Ctrl+Shift+H:<Control-Shift-KeyPress-H>
mainloop()
示例32:消息組件 Message | 輸入組件 Spinbox
from tkinter import *
root = Tk()
root.title('Module')
#消息組件:Message
m1 = Message(root, text='這是一個消息:', width=100)
m1.pack()
m2 = Message(root, text='這是一\n則駭人聽聞的長長長長長長長消息!', 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)
'''
#三窗格,同時顯示隱藏布局線(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)建頂級窗口,即彈出窗口)
from tkinter import *
root = Tk()
root.title('Toplevel')
def create():
? ? top = Toplevel()
? ? #top.attributes('-alpha', 0.5) 設(shè)置彈出的頂級窗口透明度:50%
? ? top.title('Toplevel demo...')
? ? msg = Message(top, text='I love python...')
? ? msg.pack()
Button(root, text='創(chuàng)建頂級窗口', command=create).pack() ?#點擊出現(xiàn)頂級窗口
mainloop()
示例35:幾何管理類,包pack(),網(wǎng)格grid(),位置place()
#pack() ?注意pack和grid不要混合使用
from tkinter import *
root = Tk()
root.title('pack')
#Listbox完全填充測試
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')
#兩個sticky=W實現(xiàn)第一列左對齊
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() ? 可以實現(xiàn)一些pack和grid實現(xiàn)不了的布局
from tkinter import *
root = Tk()
root.title('place')
#place位置布局測試
'''
photo = PhotoImage(file='tk_image.png')
Label(root, image=photo).pack() ?#按鈕就會出現(xiàn)在圖片的組件上,實現(xiàn)組件疊加顯示
def callback():
? ? print('正中靶心!!!')
#relx,rely相對父組件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:對話框 (警告 showinfo | 消息 messagebox | 文件 filedialog | 顏色 colorchooser)
from tkinter import *
from tkinter import messagebox ? ?#messagebox()需要單獨導(dǎo)入
from tkinter import filedialog ? ?#filedialog()需要單獨導(dǎo)入
from tkinter import colorchooser ?#colorchooser()需要單獨導(dǎo)入
from tkinter.messagebox import * ?#用戶使用showinfo()
#警告對話框
showinfo(title='test', message='警告')
#消息對話框
result = messagebox.askokcancel('demo', '發(fā)射核彈?') ?#返回值是True或False
print(result) ?#根據(jù)用戶按下了確定還是取消做進一步的操作
#文件對話框
root = Tk()
def callback1():
? ? filename = filedialog.askopenfilename(defaultextension='.py') ?#指定文件后綴
? ? print(filename) ?#返回的是文件的完整路徑
Button(root, text='打開文件', command=callback1).pack()
#顏色選擇對話框
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()
python學(xué)習(xí)環(huán)境:(python3)win10下python3.5.4的IDLE ?+ ?ubuntu下python3輔助
python分享范圍:適合有C/C++/JAVA任意語言之一為基礎(chǔ),不適合純新手入門
python語言優(yōu)勢:至今還沒有一門編程語言,開發(fā)速度比Python快,運行速度比C快
python常用工具手冊:
http://bbs.fishc.com/forum.php?mod=collection&action=view&ctid=198
---------------------------------2017.08.27--------------------------------------
00丶python背景與特點
Python語言起源
在1989年末,Guido van Rossum為了打發(fā)圣誕節(jié)的無聊,創(chuàng)造了python(大蟒蛇)。 1991年,第一個 Python 版本誕生。最新版本是Python3 3.6.2 。Guido van Rossum 是蒙提·派森的飛行馬戲團(Monty Python‘s Flying Circus)的愛好者。logo是由兩只蟒蛇的圖形組成。
官網(wǎng)下載地址:
https://www.python.org/downloads/
Python 3 與 Python 2 不完全兼容
官方表示對 Python2 支持到2020年, Python2 2.7.13。Python 2 的生態(tài)庫遠遠大于 Python 3。
簡單:
學(xué)習(xí)曲線平滑, 45分鐘學(xué)會基本使用,使用簡單。
跨平臺:
一次編寫、到處運行。 Windows, Linux, Mac, Android
功能強大:
? ? 動態(tài)類型、自動內(nèi)存管理
? ? 非常實用的內(nèi)置對象類型
? ? 強大的內(nèi)置工具和標準庫
? ? 易于擴展,很多成熟易用第三方庫
? ? 大型程序支持
應(yīng)用廣泛:
? ? 數(shù)據(jù)庫、網(wǎng)絡(luò)、圖形圖像、科學(xué)計算、機器學(xué)習(xí)、web開發(fā)、操作系統(tǒng)擴展等
缺點:
運行速度不夠快(硬件的發(fā)展可以為此彌補不足)
開發(fā)速度與運行速度之間的矛盾:
至今還沒有一門編程語言,開發(fā)速度比Python快,運行速度比C快
知名軟件包:Django/Numpy/Pandas/Matplotlib/PIL (Pillow)/PyQt5/Tensorflow/Scipy/Theano/NLTK
知名項目:(網(wǎng)站)豆瓣/知乎/美團/Gmail/Youtube/Instagram/Calibre/……
01丶第一次親密接觸 first love
(1) win下的python IDLE集成開發(fā)環(huán)境自動縮進,table鍵補齊變量名
(2) linux下使用vi編輯.py的python文件,需要聲明 #!/usr/bin/python3
(3) python使用等量(1個tab)的縮進來嚴格對齊表示作用域
#!/usr/bin/python3
#guess game
print ("---------游戲開始-----------")
temp = input ("輸入一個我現(xiàn)在想的數(shù)字:")
guess = int (temp)
if guess == 8:
print ("猜對了!!!")
else:
print ("哈哈,猜錯了。。")
print ("游戲結(jié)束嘍~")
#---end---
BIF == Built-in functions(內(nèi)置函數(shù))
>>> dir(__builtins__)
..., 'input', ...
>>> help(input)
#可以查詢內(nèi)置函數(shù)的說明和用法,類似于C語言的man手冊
02丶變量 variable
(1) python沒有"變量"只有"名字"
(2) 變量使用之前,需要對其先賦值
(3) 變量名命名同C的規(guī)則,不能以數(shù)字開頭,保證可讀性命名即可
(4) 大小寫敏感,區(qū)分
(5) =左右依次為左值和右值
(6) 十六進制,以0x 或 0X 開頭 ,數(shù)字由"0"到"9" 或者 "a"到"f" 或者 "A"到"F"組成
八進制,0o或0O 開頭,數(shù)字由"0" 到 "7"組成
二進制,0b或0B 開頭表示,數(shù)字由"0" 或者"1"組成
十進制由數(shù)字"0"到"9"組成,并且不能以0開頭
>>> 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ōu)先級 precedence of operator
#符合數(shù)學(xué)運算優(yōu)先原則,括號最優(yōu)先,最安全。
lambda lambda表達式
or 布爾或
and 布爾與
not 布爾非
in 和 not in 成員是否屬于測試
is 和 is not 對象是否是同一個
> ?>= ?< ?<= ?== ?!= 比較操作符
| 按位或
^ 按位異或
& 按位與
<< 和 >> 移位
+ 和 - 加法和減法
* 和 / 和 % 乘法、除法、取余
+x 和 -x 正負號
~x 按位翻轉(zhuǎn)
** 指數(shù)(冪運算)
// 地板除法,舍棄小數(shù)部分
---python運算符優(yōu)先級(圖)---
#=連續(xù)賦值,自右向左,同C語言
>>> 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)、浮點型(float)、布爾類型(bool)、e記法(科學(xué)計數(shù)法,屬于float)
(1) 整型與浮點型的區(qū)別就是是否含有小數(shù)點'.'
(2) bool類型的值是以大寫開頭的兩個單詞: True / False
(3) 純數(shù)字的字符串可以使用int轉(zhuǎn)為數(shù)字,進而參與計算,相當(dāng)于C的atoi,非純數(shù)字的不能使用int轉(zhuǎn)換為數(shù)字
(4) float類型轉(zhuǎn)換為int類型時,會丟棄小數(shù)部分
(5) str類型均可被其他類型轉(zhuǎn)換,即變成字符串無障礙
(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)鍵字后面的條件為假的時候,程序自動崩潰并拋出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以空格隔開
s t r i n g
range()函數(shù)
range ([start], [stop], [step]) ?#step默認每次遞增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語言的break和continue,依次為跳出循環(huán)和跳過當(dāng)前循環(huán)。
pass 和 del 和 exec
pass 什么也不敢,暫時預(yù)留
del 刪除不再使用的對象
exec 執(zhí)行python語句
exal 計算python表達式,并返回結(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()
功能:列表長度(元素個數(shù))
len(listname)
>>> len(member)
4
append()
功能:向列表添加單個元素
listname.append(element)
>>> member.append('class')
>>> member
['name', 'id', 'age', 'weight', 'class']
extend()
功能:使用子列表擴展列表
listname.extend([element1, element2, ...])
>>> member.extend (['str1', 'str2'])
>>> member
['name', 'id', 'age', 'weight', 'class', 'str1', 'str2']
insert()
功能:向列表指定位置插入元素
listname.insert(position, element)
#list和數(shù)組一樣,下標/索引均從0開始
>>> member.insert (1, 'new_elem')
>>> member
['name', 'new_elem', 'id', 'age', 'weight', 'class', 'str1', 'str2']
列表元素訪問
listname[index]
#index從0開始,到index-1位置的索引訪問
列表元素刪除
listname.remove(element) #刪除元素element
del listname[index] #刪除index位置的元素
listname.pop() #刪除最后一個元素,相當(dāng)于C語言的彈棧
listname.pop(index) #刪除index位置指定的元素
列表元素分片
listname[start_index:stop_index]
(1) 分片不會修改原列表的值,輸出的是一份拷貝
(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)] #訪問最后3個元素
['str1', 'str2', 'str3']
>>> member[0:len(member):2] #最后的2代表步長
['name', 'age', 'class', 'str2']
列表常用操作符
(1) list元素的判斷只會判斷第一個元素,然后理解返回bool結(jié)果
(2) list支持比較、邏輯、連接(+)、重復(fù)(*)、成員關(guān)系(in)操作符
(3) list賦值list時需要注意加上[:],左值會表現(xiàn)為一份拷貝
示例:
list2 = list1[:]#list2是list1的一份拷貝
list3 = list1 #list3是list1的一個引用(list1被修改,list3也會跟著被修改)
(4) dir(list) 查看list支持的所有方法:
listname.count(element)#element元素出現(xiàn)的次數(shù)
listname.index(element, [range_s], [rang_t])#查找元素在起止范圍里第一次出現(xiàn)的下標位置
listname.reverse()#將list中的元素原地翻轉(zhuǎn)
listname.sort()#將list中的元素進行排序,默認從小到大(修改原list內(nèi)容)
listname.sort(reverse=True)#排序元素,實現(xiàn)從大到小(修改原list內(nèi)容)
07丶元組 tuple
元組和列表使用上相似:
(1) 最大區(qū)別:列表可以任意修改和插入等操作,元組是不可改變的
(2) 創(chuàng)建:列表使用[],元組使用()
元組只有1個元素時使用(element,)注意逗號
()可以省略,但是,逗號不能省略
(3) 訪問:都使用name[index]來訪問
(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) \可以進行符號轉(zhuǎn)義
(2) 單引號等同于雙引號
(3) 定義字符串時使用r寫在右值前面聲明為原始字符串
(4) 使用三引號('''或""")可以指定多行字符串。并且字符串里可以包含單引號和雙引號'''
(5) +號運算符可以連接字符串為1個字符串
(6) *號運算符可以復(fù)制多個相同字符串
列表和元組應(yīng)用于字符串,所有標準的序列操作均適用于字符串。
>>> 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() 返回新字符串,把字符串的第一個字符改為大寫
casefold() 返回新字符串,把整個字符串的所有字符改為小寫
center(width) 將字符串居中,并使用空格填充至長度 width 的新字符串
count(sub[, start[, end]]) 返回 sub 在字符串里邊出現(xiàn)的次數(shù),start 和 end 參數(shù)表示范圍,可選。
encode(encoding='utf-8', errors='strict') 以 encoding 指定的編碼格式對字符串進行編碼。
endswith(sub[, start[, end]]) 檢查字符串是否以 sub 子字符串結(jié)束,如果是返回 True,否則返回 False。start 和 end 參數(shù)表示范圍,可選。
expandtabs([tabsize=8]) 把字符串中的 tab 符號(\t)轉(zhuǎn)換為空格,如不指定參數(shù),默認的空格數(shù)是 tabsize=8。
find(sub[, start[, end]]) 檢測 sub 是否包含在字符串中,如果有則返回索引值,否則返回 -1,start 和 end 參數(shù)表示范圍,可選。
index(sub[, start[, end]]) 跟 find 方法一樣,不過如果 sub 不在 string 中會產(chǎn)生一個異常。
isalnum() 如果字符串至少有一個字符并且所有字符都是字母或數(shù)字則返回 True,否則返回 False。
isalpha() 如果字符串至少有一個字符并且所有字符都是字母則返回 True,否則返回 False。
isdecimal() 如果字符串只包含十進制數(shù)字則返回 True,否則返回 False。
isdigit() 如果字符串只包含數(shù)字則返回 True,否則返回 False。
islower() 如果字符串中至少包含一個區(qū)分大小寫的字符,并且這些字符都是小寫,則返回 True,否則返回 False。
isnumeric() 如果字符串中只包含數(shù)字字符,則返回 True,否則返回 False。
isspace() 如果字符串中只包含空格,則返回 True,否則返回 False。
istitle() 如果字符串是標題化(所有的單詞都是以大寫開始,其余字母均小寫),則返回 True,否則返回 False。
isupper() 如果字符串中至少包含一個區(qū)分大小寫的字符,并且這些字符都是大寫,則返回 True,否則返回 False。
join(sub) 以字符串作為分隔符,插入到 sub 中所有的字符之間。
ljust(width) 返回一個左對齊的字符串,并使用空格填充至長度為 width 的新字符串。
lower() 轉(zhuǎn)換字符串中所有大寫字符為小寫。
lstrip() 去掉字符串左邊的所有空格
partition(sub) 找到子字符串 sub,把字符串分成一個 3 元組 (pre_sub, sub, fol_sub),如果字符串中不包含 sub 則返回 ('原字符串', '', '')
replace(old, new[, count]) 把字符串中的 old 子字符串替換成 new 子字符串,如果 count 指定,則替換不超過 count 次。
rfind(sub[, start[, end]]) 類似于 find() 方法,不過是從右邊開始查找。
rindex(sub[, start[, end]]) 類似于 index() 方法,不過是從右邊開始。
rjust(width) 返回一個右對齊的字符串,并使用空格填充至長度為 width 的新字符串。
rpartition(sub) 類似于 partition() 方法,不過是從右邊開始查找。
rstrip() 刪除字符串末尾的空格。
split(sep=None, maxsplit=-1) 不帶參數(shù)默認是以空格為分隔符切片字符串,如果 maxsplit 參數(shù)有設(shè)置,則僅分隔 maxsplit 個子字符串,返回切片后的子字符串拼接的列表。
splitlines(([keepends])) 按照 '\n' 分隔,返回一個包含各行作為元素的列表,如果 keepends 參數(shù)指定,則返回前 keepends 行。
startswith(prefix[, start[, end]]) 檢查字符串是否以 prefix 開頭,是則返回 True,否則返回 False。start 和 end 參數(shù)可以指定范圍檢查,可選。
strip([chars]) 刪除字符串前邊和后邊所有的空格,chars 參數(shù)可以定制刪除的字符,可選。
swapcase() 翻轉(zhuǎn)字符串中的大小寫。
title() 返回標題化(所有的單詞都是以大寫開始,其余字母均小寫)的字符串。
translate(table) 根據(jù) table 的規(guī)則(可以由 str.maketrans('a', 'b') 定制)轉(zhuǎn)換字符串中的字符。
upper() 轉(zhuǎn)換字符串中的所有小寫字符為大寫。
zfill(width) 返回長度為 width 的字符串,原字符串右對齊,前邊用 0 填充。
字符串操作:格式化
(1) 通過format方法將位置參數(shù)傳遞給對應(yīng)字段
(2) : 冒號表示格式化符號的開始
位置參數(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ù)必須在關(guān)鍵字參數(shù)的前面。
字符串格式化符號含義
%c 格式化字符及其 ASCII 碼
%s 格式化字符串
%d 格式化整數(shù)
%o 格式化無符號八進制數(shù)
%x 格式化無符號十六進制數(shù)
%X 格式化無符號十六進制數(shù)(大寫)
%f 格式化浮點數(shù)字,可指定小數(shù)點后的精度,默認精確到小數(shù)點后6位
%e 用科學(xué)計數(shù)法格式化浮點數(shù)
%E 作用同 %e,用科學(xué)計數(shù)法格式化浮點數(shù)
%g 根據(jù)值的大小決定使用 %f 或 %e
%G 作用同 %g,根據(jù)值的大小決定使用 %f 或者 %E
舉例:
>>> '%c' % 97 # 此處 % 為占位符,同C語言中printf函數(shù)中的%
'a'
>>> '%c %c %c' % (97, 98, 99) #此處的元組()小括號不能省略
'a b c'
格式化操作符輔助命令
m.n m 是顯示的最小總寬度,n 是小數(shù)點后的位數(shù)
- 用于左對齊
+ 在正數(shù)前面顯示加號(+)
# 在八進制數(shù)前面顯示 '0o',在十六進制數(shù)前面顯示 '0x' 或 '0X'
0 顯示的數(shù)字前面填充 '0' 取代空格
舉例:
>>> '%5.1f' % 27.658 #m.n
' 27.7'
>>> '%-10d' % 5 #填充的位數(shù)都是空格
'5 ? ? ? ? ?'
>>> '%#x' % 160 #對應(yīng)進制顯示方式
'0xa0'
>>> '%010d' % 5 #用0填充。'%-010d' % 5 負號的時候填充的只會是空格
'0000000005'
Python 的轉(zhuǎn)義字符及其含義
\' 單引號
\" 雙引號
\a 發(fā)出系統(tǒng)響鈴聲
\b 退格符
\n 換行符
\t 橫向制表符(TAB)
\v 縱向制表符
\r 回車符
\f 換頁符
\o 八進制數(shù)代表的字符
\x 十六進制數(shù)代表的字符
\0 表示一個空字符
\\ 反斜杠
09丶序列方法 sequence method
列表、元組、字符串的共同點:
(1) 都可以通過索引得到每一個元素
(2) 默認索引值總是從0開始
(3) 可以通過分片的方法得到一個范圍內(nèi)的元素的集合
(4) 有很多共同的操作符(重復(fù)*、拼接+、成員關(guān)系in/not in等)
(5) 統(tǒng)稱為序列,以下(成員函數(shù))為序列方法
list()
list(iterable) 把一個可迭代對象轉(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) 把一個可迭代對象轉(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ù),會加在一起
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)一個序列的內(nèi)容
>>> reversed(sequence)
舉例:
>>> numbers = [1, 24, 5, -98, 54, 32]
>>> reversed(numbers)
<list_reverseiterator object at 0x000002C3EE5046A0>#這種格式都是:迭代器對象
>>> list(reversed(numbers)) # 將迭代器對象轉(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(...) 返回由各個參數(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): ?#并行迭代,同時迭代兩個變量
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)沒有過程(no return)
(2) 函數(shù)返回多個值的時候,使用list列表或tuple元組進行返回
(3) 局部變量和全局變量的規(guī)則同C語言
(4) 在函數(shù)內(nèi)部使用 global 修飾變量,使函數(shù)可以修改同名的全局變量
(5) 函數(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): #形參:多個參數(shù)使用,逗號隔開
#函數(shù)體使用參數(shù)param
function_name(parameter) #實參:傳遞實際參數(shù)
函數(shù)文檔
舉例:
>>> def my_sec_func(name):
'function document.'#函數(shù)文檔部分,單引號引起來即可
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ù)與默認參數(shù)
舉例:
>>> def say_some(name, words):
#>> def say_some(name='abc', words='string'): #形參可設(shè)置默認值
print(name + ' -> ' + words)
>>> say_some('Jan', 'learning python.')
Jan -> learning python.
>>> say_some(words='learning python.', name='Jan') #指定形參對應(yīng)實參
Jan -> learning python.
#>>> say_some()
#abc -> string
*params搜集其余的位置參數(shù)
>>> def test(*params): # *params把實參打包為元組
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) #注意傳參需要單獨指定
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...
閉包closure
舉例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] #對func2函數(shù)來說x是全局變量,在func2中沒有定義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 表達式(匿名函數(shù))
(1) 不需要考慮函數(shù)名的命名問題
(2) 極大簡化函數(shù)編寫的步驟
舉例:
>>> def ds(x):
return 2*x + 1
>>> ds(5)
11
>>> lambda x : 2*x + 1
<function <lambda> at 0x000002170B3D87B8> #可以理解為返回的是C語言的函數(shù)指針
>>> g = lambda x : 2*x + 1 #賦值后,傳參即可,g相當(dāng)于接收了匿名函數(shù)
>>> g(5)
11
>>> g = lambda x, y : x+y #lambda匿名函數(shù)多個參數(shù)
>>> g(1, 3)
4
兩個牛逼的BIF:filter和map
(1) filter 過濾:返回其函數(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] #驗證filter過濾的是非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))) ?#簡化一行實現(xiàn)求奇數(shù)
[1, 3, 5, 7, 9]
(2) map 映射:對序列中每個元素都應(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語言
? ? else:
? ? ? ? return n * factorial(n-1) #(2)必須調(diào)用函數(shù)自身,同C語言
number = int(input("請輸入一個正整數(shù):"))
result = factorial(number)
print("%d 的階乘為:%d" % (number, result))
#運行:
請輸入一個正整數(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("請輸入一個數(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個盤子從x移動到y(tǒng)上
? ? ? ? print(x, '-->', z) ? ? ?#將最底下的最后一個盤子從x移動到z上
? ? ? ? hanoi(n-1, y, x, z) ? ? #將y上的n-1個盤子移動到z上
n = int(input('請輸入漢諾塔的層數(shù):'))
hanoi(n, 'x', 'y', 'z')
---------------------------------2017.08.29--------------------------------------
12丶字典 dict
(1) 字典是一種映射類型(key:value 鍵值映射項),類型名為 dict
(2) 字典的表示使用{}大括號,元素映射之間使用:冒號,使用dictname[]訪問字典映射的值
(3) 新建字典有兩種方法:三層小括號,一層小括號中key=value
(4) 字典中的鍵值映射項是無序的,popitem時是隨機彈出
(5) 字典基本操作:
len(d) 返回d中項的數(shù)量
d[k] 返回映射到鍵k上的值
d[k]=v 將值v映射到鍵k上
del d[k] 刪除鍵為k的項
k in d 檢查d中是否含有鍵為k的項
(6) 字典常用方法: clear()/copy()/fromkeys()/get()/has_key()/items()/iteritems()/keys()/iterkeys()/pop()/popitem()/setdefault()/update()/values()/itervalues()
映射關(guān)系示例
>>> brand = ['李寧', '耐克', '阿迪達斯', 'xx工作室']
>>> slogan = ['一切皆有可能', 'Just do it', 'Impossible is nothing', '讓編程改變世界']
>>> print('魚c工作室的口號是: ', slogan[brand.index('xx工作室')])
xx工作室的口號是: ?讓編程改變世界
#使用字典來完成映射工作
>>> dict1 = {'李寧':'一切皆有可能', '耐克':'Just do it', '阿迪達斯':'Impossible is nothing', 'xx工作室':'讓編程改變世界'}
>>> print('xx工作室的口號是: ', dict1['xx工作室'])
xx工作室的口號是: ?讓編程改變世界
#新建一個字典方法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}
#新建一個字典方法2:(key1=value1, key2=value2, ...)
>>> dictname = dict(蒼井空='讓AV改變宅男', 工作室='讓編程改變世界')
>>> dictname
{'工作室': '讓編程改變世界', '蒼井空': '讓AV改變宅男'}
>>> dictname['蒼井空']
'讓AV改變宅男'
#字典中新增映射元素
>>> dictname['愛迪生'] = '天才是99%的汗水+1%的靈感,但這1%的靈感比99%的汗水更重要。'
>>> dictname
{'工作室': '讓編程改變世界', '愛迪生': '天才是99%的汗水+1%的靈感,但這1%的靈感比99%的汗水更重要。', '蒼井空': '讓AV改變宅男'}
字典中鍵、值、鍵值映射項的訪問
>>> 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)建并返回一個新的字典
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'} ? #還是返回新的字典,并不會修改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但在字典里如果找不到的話會將映射項添加到字典中
dictname.setdefault(key, value)
舉例:
>>> a
{3: 'three', 4: 'four'}
>>> a.setdefault(5, '小白')
'小白'
>>> a
{3: 'three', 4: 'four', 5: '小白'}
clear() ?清空一個字典(包括使用當(dāng)前字典賦值的其他字典)
舉例:
>>> dict1.clear()
>>> dict1
{}
copy() ?拷貝一個字典(淺拷貝,不受字典修改影響)
>>> a = {1:'one', 2:'two', 3:'three'}
>>> b = a.copy()
>>> c = a #相當(dāng)于C的指針,C++的引用,修改字典c的值會同時影響字典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(...) ?給定一個鍵彈出一個值
popitem() ?隨機彈出一個項(映射關(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(...) ?使用一個子字典去更新原字典
dictname1.update(dictname2)
舉例:
>>> a
{3: 'three', 4: 'four', 5: '小白'}
>>> b = {'小白':'狗'}
>>> a.update(b)
>>> a
{'小白': '狗', 3: 'three', 4: 'four', 5: '小白'}
13丶集合 set
(1) 使用{}創(chuàng)建的沒有映射關(guān)系的字典,成為集合類型,如num = {1, 2, 3, 4, 5}
(2) 集合中元素唯一,重復(fù)的數(shù)據(jù)會被自動清理掉
(3) 集合中元素?zé)o序,不能索引取到其元素的值
(4) 集合使用關(guān)鍵字 set([]) 來創(chuàng)建
(5) 集合支持 in 和 not in 來判斷是否屬于集合
舉例:
>>> num = {}
>>> type(num)
<class 'dict'>
#set沒有體現(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無序性
>>> 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實現(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]
#簡化: 實現(xiàn)set的唯一性,并且會把set的無序性變?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)建方法(整理出來):
http://bbs.fishc.com/forum.php?mod=viewthread&tid=45276&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
14丶文件操作 file operation
open(...) ?打開一個文件返回一個流對象
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) ?#除了file參數(shù),其他參數(shù)均有默認值
'r' 只讀模式
'w' 寫入(會覆蓋已存在的文件)模式
'x' 文件存在,報異常的模式
'a' 寫入(文件存在則追加)模式
'b' 二進制模式
't' 文本模式
'+' 可讀寫模式(可添加到其他模式)
'U' 通用換行符支持
舉例:
#打開一個文件,注意路徑的中\(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'>
文件對象方法
(整理)
http://bbs.fishc.com/forum.php?mod=viewthread&tid=45279&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
(1) 文件對象支持直接使用list轉(zhuǎn)換讀出
(2) 文件對象支持 for...in 的迭代方式讀取
舉例:
>>> f = open('C:\\Users\\Jan\\Desktop\\IP.txt') #f,打開的文件流對象
>>> f.read()
'【本機】\nIP:192.168.31.217\n[ Ctrl + r ]\ncmd\nping 192.168.31.207\nmstsc\n\n\n【虛擬機】 - 虛擬網(wǎng)絡(luò)編輯器(自動) - 橋接模式\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)
'【本機】\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', '【虛擬機】 - 虛擬網(wǎng)絡(luò)編輯器(自動) - 橋接模式\n', 'IP:192.168.31.207\n', 'linux賬戶:jiangyuan\n', 'linux密碼:123456\n']
>>> for each_line in f:
print(each_line)#逐行讀取文件內(nèi)容的高效方法
【本機】
IP:192.168.31.217
[ Ctrl + r ]
cmd
ping 192.168.31.207
mstsc
...
#創(chuàng)建一個新的可寫入的文件,寫入內(nèi)容,然后關(guān)閉文件流對象
>>> f = open('C:\\Users\\Jan\\Desktop\\test.txt', 'w')
>>> f.write('some lines')
10
>>> f.close()
任務(wù):將文件record.txt中的數(shù)據(jù)進行分割并且按照規(guī)律保存起來。
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] != '======':
? ? ? ? ? ? # 我們再這里進行字符串分割操作
? ? ? ? ? ? (role, line_spoken) = each_line.split(':', 1) ?#中文冒號:否則會報錯
? ? ? ? ? ? if role == '小甲魚':
? ? ? ? ? ? ? ? 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) 使用模塊是需要進行導(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個人總資料', 'Qiyi', 'QQMusicCache', 'qycache', 'System Volume Information', 'Youku Files', 'Youxun', '博客'] ?#RECYCLE.BIN是個回收站
>>> 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') ?#運行系統(tǒng)的shell命令:windows shell窗口
-1073741510
>>> os.system('calc') ?#運行系統(tǒng)的shell命令:calc計算器
0
>>> os.curdir ?#當(dāng)前目錄('.')
'.'
>>> os.listdir(os.curdir) ?# 等同于 os.listdir('.')
['$RECYCLE.BIN', '.cache', '360Downloads', 'A', 'Jan_mi', 'Jan個人總資料', 'Qiyi', 'QQMusicCache', 'qycache', 'System Volume Information', 'Youku Files', 'Youxun', '博客']
>>> os.sep ?#輸出操作系統(tǒng)特定的路徑分隔符(Win下為'\\',Linux下為'/')
'\\'
>>> os.linesep ?#當(dāng)前平臺使用的行終止符(Win下為'\r\n',Linux下為'\n')
'\r\n'
>>> os.name ?#指代當(dāng)前使用的操作系統(tǒng)(包括:'posix', ?'nt', 'mac', 'os2', 'ce', 'java')
'nt' ?#nt是windows系統(tǒng)平臺
os.path 模塊(系統(tǒng)路徑模塊屬于os的子模塊)
>>> os.path.basename('E:\\A\\B\\C\\sexy.avi') ?#去掉目錄路徑,單獨返回文件名
'sexy.avi'
>>> os.path.dirname('E:\\A\\B\\C\\sexy.avi') ?#去掉文件名,單獨返回目錄路徑
'E:\\A\\B\\C'
>>> os.path.join('A', 'B', 'C') ?#將path1, path2...各部分組合成一個路徑名
'A\\B\\C'
>>> os.path.join('D:', 'A', 'B', 'C')
'D:A\\B\\C'
>>> os.path.join('D:\\', 'A', 'B', 'C') ?#注意盤符需要帶上斜杠
'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') ?#分離文件名與擴展名,返回(f_name, f_extension)元組
('E:\\A\\SEXY', '.AVI')
>>> os.path.getatime('E:\\A\\test.txt') ?#返回指定文件最近的訪問時間
1504103243.229383 ?#浮點型秒數(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:\\') ?#判斷指定路徑是否存在且是一個掛載點
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)容傾倒入文件流對象中
>>> 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的字典映射寫入文件
>>> pickle.dump(city, pickle_f)
>>> pickle_f.close()
>>> pickle_file = open('E:\\A\\city.pkl', 'rb') ?#使用字典的時候打開文件裝載即可
>>> city = pickle.load(pickle_file)
>>> print(city)
{'城市2': '000002', '城市n': '999999', '城市1': '000001'}
---------------------------------2017.08.31--------------------------------------
16丶異常 exception
異常匯總
AssertionError 斷言語句(assert)失敗<eg1>
AttributeError 嘗試訪問未知的對象屬性<eg2>
EOFError 用戶輸入文件末尾標志EOF(Ctrl+d)?
FloatingPointError 浮點計算錯誤?
GeneratorExit generator.close()方法被調(diào)用的時候?
ImportError 導(dǎo)入模塊失敗的時候?
IndexError 索引超出序列的范圍<eg3>
KeyError 字典中查找一個不存在的關(guān)鍵字<eg4>
KeyboardInterrupt 用戶輸入中斷鍵(Ctrl+c)?
MemoryError 內(nèi)存溢出(可通過刪除對象釋放內(nèi)存)?
NameError 嘗試訪問一個不存在的變量?
NotImplementedError 尚未實現(xiàn)的方法?
OSError 操作系統(tǒng)產(chǎn)生的異常(例如打開一個不存在的文件)?
OverflowError 數(shù)值運算超出最大限制?
ReferenceError 弱引用(weak reference)試圖訪問一個已經(jīng)被垃圾回收機制回收了的對象?
RuntimeError 一般的運行時錯誤?
StopIteration 迭代器沒有更多的值?
SyntaxError Python的語法錯誤?
IndentationError 縮進錯誤?
TabError Tab和空格混合使用?
SystemError Python編譯器系統(tǒng)錯誤?
SystemExit Python編譯器進程被關(guān)閉?
TypeError 不同類型間的無效操作?
UnboundLocalError 訪問一個未初始化的本地變量(NameError的子類)?
UnicodeError Unicode相關(guān)的錯誤(ValueError的子類)?
UnicodeEncodeError Unicode編碼時的錯誤(UnicodeError的子類)?
UnicodeDecodeError Unicode解碼時的錯誤(UnicodeError的子類)?
UnicodeTranslateError Unicode轉(zhuǎn)換時的錯誤(UnicodeError的子類)?
ValueError 傳入無效的參數(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 #斷言語句(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'#嘗試訪問未知的對象屬性
>>> 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' #字典中查找一個不存在的關(guān)鍵字
>>> my_dict.get('four')
>>> #dict.get(...)方法比較安全合適
異常檢測與處理
(1) try語句一旦檢測出現(xiàn)異常,則剩下的其他代碼則不會執(zhí)行
(2) raise Exception_name 主動引發(fā)一個自定義異常名字的異常,可定義異常描述
try:
#檢測范圍
except Exception[as reason]:
#出現(xiàn)異常(Exception)后的處理代碼
finally:
#無論如何都會被執(zhí)行的代碼(收尾工作)
舉例:
try:
? ? f = open('我為什么是一個文件.txt')
? ? print(f.read())
? ? f.close()
except OSError:
? ? print('文件出錯啦T_T')
運行:
文件出錯啦T_T
try:
? ? f = open('我為什么是一個文件.txt')
? ? print(f.read())
? ? f.close()
except OSError as reason:
? ? print('文件出錯啦T_T\n錯誤的原因是:' + str(reason))
運行:
文件出錯啦T_T
錯誤的原因是:[Errno 2] No such file or directory: '我為什么是一個文件.txt'
try:
? ? sum = 1 + '1'
? ? f = open('我為什么是一個文件.txt')
? ? print(f.read())
? ? f.close()
except (OSError, TypeError): ?#多個異常同時捕獲
? ? print('出錯啦T_T')
運行:出錯啦T_T
try:
? ? f = open('我為什么是一個文件.txt', 'w')
? ? print(f.write('我存在了!')) ?#沒有finally時并不會寫入文件
? ? sum = 1 + '1'
? ? f.close()
except (OSError, TypeError):
? ? print('出錯啦T_T')
finally:
? ? f.close()
運行:
5
出錯啦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-簡潔的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)完沒有break就會執(zhí)行else
? ? ? ? print('%d是素數(shù)!' % num)
num = int(input('請輸入一個數(shù):'))
showMaxFactor(num)
舉例:try-else
try:
? ? print(int('123'))
except ValueError as reason:
? ? print('出錯啦:' + str(reason))
else:
? ? print('Good!沒有任何異常。')
運行:
123
Good!沒有任何異常。
with as
舉例:
try:
? ? with open('data.txt', 'w') as f: #比 f = open(...) 多了文件不使用時自動關(guān)閉功能
? ? for each_line in f:
? ? ? ? print(each_line)
except OSError as reason:
? ? print('出錯啦:' + str(reason))
#finally: ? ? ? #有了with就不需要finally去調(diào)用關(guān)閉,會自動關(guān)閉
# ? ?f.close() ?#如果文件data.txt不存在就試圖去關(guān)閉一個不存在的文件
18丶圖形用戶界面 EasyGui
EasyGui官網(wǎng):http://easygui.sourceforge.net
中文的教學(xué)文檔:http://bbs.fishc.com/thread-46069-1-1.html (要看完并實操)
模塊庫: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è)置-以管理員身份運行此程序-確定
> "C:\Program Files (x86)\python\python.exe" setup.py install
#生成了文件模塊庫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 出錯~!!!
【解決辦法】
(1) 重裝python IDLE勾選添加python路徑,選擇目錄安裝到C:\python文件夾,如重裝則忽略(2),如此一來win-cmd下的python中sys.path和IDLE中的sys.path則一致了。
(2) 對比windows命令窗口中啟動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)入模塊的同時重定義模塊名字
>>> g.msgbox('嗨,python!')
'OK'
>>>?
# No error, success... 但每次重啟IDLE都需要將windows下的sys.path進行添加。
# 示例,gui界面文字小游戲
import easygui as g
import sys
while 1:
? ? ? ? g.msgbox("嗨,歡迎進入第一個界面小游戲^_^")
? ? ? ? msg ="請問你希望在魚C工作室學(xué)習(xí)到什么知識呢?"
? ? ? ? title = "小游戲互動"
? ? ? ? choices = ["談戀愛", "編程", "OOXX", "琴棋書畫"]
? ? ? ??
? ? ? ? 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 = "你希望重新開始小游戲嗎?"
? ? ? ? title = "請選擇"
? ? ? ??
? ? ? ? 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丶類和對象 class and object
面向?qū)ο?Object Oriented)
(1) python約定類名以大寫字母開頭
(2) 面向?qū)ο筇卣?#xff1a;封裝(信息隱蔽)、繼承(子類共享父類公共內(nèi)容)、多態(tài)(不同對象對同一方法響應(yīng)不同的行動)
類的示例:
class Turtle:
#屬性
color = 'green'
weight = 60
legs = 2
shell = True
age = 26
#方法
def climb(self):
print('我正在學(xué)習(xí)...')
def run(self):
print('我正在奔跑...')
運行:
>>> tt = Turtle() ?#類Turtle的示例對象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對象中
>>> list1
[1, 2, 3, 5, 7]
>>> list1.append(9) ?#append() 方法封裝在list1對象中
>>> 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() ?#不同對象對同一方法響應(yīng)不同的行動
我是小A
>>> b.fun() ?#不同對象對同一方法響應(yīng)不同的行動
我是小B
self
相當(dāng)于C++的this指針(指向當(dāng)前對象本身的地址),表明類自身
舉例:
>>> class Ball:
def setName(self, name): ?#默認self的寫法
self.name = name
def kick(self): ?#默認self的寫法
print('我叫%s, 該死的誰踢我...' % self.name)
>>> a = Ball()
>>> a.setName('球A')
>>> b = Ball()
>>> b.setName('球B')
>>> c = Ball()
>>> c.setName('土豆')
>>> a.kick()
我叫球A, 該死的誰踢我...
>>> c.kick()
我叫土豆, 該死的誰踢我...
魔法方法:__init__(self)
__init__(self, parma1, parma2, ...)
舉例:
>>> class Ball:
def __init__(self, name):
self.name = name
def kick(self):
print('我叫%s,該死的,誰踢我!!' % self.name)
>>> b = Ball('土豆')
>>> b.kick()
我叫土豆,該死的,誰踢我!!
>>> a = Ball() ?#__init__默認設(shè)置了name,所以必須傳遞name實參,否則報錯
TypeError: __init__() missing 1 required positional argument: 'name'
公有和私有
name mangling 名字改變/名字重造
公有成員:默認創(chuàng)建的成員均為公有。
私有成員:
(1) 在變量或函數(shù)名前加上"_"兩個下劃線即可。
(2) python中類的私有均屬于偽私有,通過"對象._類_變量"的形式可以訪問私有成員
舉例:
>>> 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中類的私有屬于偽私有,此方式可訪問私有成員
'yuan.jiang'
繼承 inherit
class DerivedClassName(BaseClassName):
...
(1) 如果子類中定義于父類同名的成員時,則會自動覆蓋父類對應(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): ?#重寫了__init__方法覆蓋了父類的__init__子類無法調(diào)用到self.x和self.y屬性成員,導(dǎo)致了子類無法訪問到父類的屬性或方法的問題
? ? ? ? self.hungry = True
? ? def eat(self):
? ? ? ? if self.hungry:
? ? ? ? ? ? print('吃貨的夢想就是天天有的吃^_^')
? ? ? ? ? ? self.hungry = False
? ? ? ? else:
? ? ? ? ? ? print('太撐了,吃不下了!')
運行:
>>> fish = Fish()
>>> fish.move()
我的位置是: 3 0
>>> fish.move()
我的位置是: 2 0
>>> goldfish = Goldfish()
>>> goldfish.move()
我的位置是: 4 9
>>> goldfish.move()
我的位置是: 3 9
>>> shark = Sharkfish()
>>> shark.eat()
吃貨的夢想就是天天有的吃^_^
>>> shark.eat()
太撐了,吃不下了!
>>> shark.move() ?#無法訪問到父類的__init__()方法中的x變量
AttributeError: 'Sharkfish' object has no attribute 'x'
--------------------------------2017.09.02----------------------------------------
覆蓋屬性或方法問題優(yōu)化
問題:針對子類屬性或方法覆蓋父類屬性或方法的情況,導(dǎo)致子類無法訪問父類中被覆蓋的屬性
(1) 調(diào)用未綁定的父類的方法
(2) 使用super方法(推薦)
舉例:
def __init__(self):
Fish.__init__(self) ?#調(diào)用未綁定的父類的方法,相當(dāng)于>>>Fish.__init__(Sharkfish)
self.hungry = True
運行:
>>> shark = Sharkfish()
>>> shark.move()
我的位置是: -1 2
>>> shark.move()
我的位置是: -2 2
舉例:
def __init__(self):
super().__init__() ?#使用super方法解決
self.hungry = True
運行:
>>> shark = Sharkfish()
>>> shark.move()
我的位置是: 8 3
>>> shark.move()
我的位置是: 7 3
多重繼承
class DerivedClassName(Base1, Base2, Base3, ...):
...
#建議少用,有可能會導(dǎo)致不可預(yù)見的bug(不可預(yù)見最麻煩)
>>> 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 只,小魚 %d 條!' % (self.turtle.num, self.fish.num))
運行:
>>> pool = Pool(1, 10)
>>> pool.print_num()
水池里總共有烏龜 1 只,小魚 10 條!
類、類對象、示例對象
類定義 ? ?C
類對象 ? ?C
實例對象 ?a ?b ?c
舉例:
>>> class C: ? #C, 既是類,也是類對象
count = 0
>>> a = C() ? ?#a,實例對象
>>> b = C() ? ?#b,實例對象
>>> c = C() ? ?#c,實例對象
>>> a.count
0
>>> b.count
0
>>> c.count
0
>>> c.count += 10
>>> c.count
10
>>> a.count
0
>>> b.count
0
>>> C.count ? ?#C,作為類對象
0
>>> C.count += 100 ? ?#C,作為類對象
>>> a.count
100
>>> b.count
100
>>> c.count
10
(1) 當(dāng)屬性名與方法名沖突,會導(dǎo)致方法不能正常調(diào)用。
(2) 一般遵循規(guī)則:屬性名用英文名詞,方法名用英文動詞。
(3) python嚴格要求方法需要有實例才能被調(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)用出錯
TypeError: 'int' object is not callable
>>> class BB:
def printBB():
print('no zuo no die.')
>>> BB.printBB()
no zuo no die.
>>> #沒有self,也沒有將類實例化
>>> 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>}) ?#使用類對象顯示類的屬性詳情
>>> dd.setXY(4, 5)
>>> dd.__dict__
{'y': 5, 'x': 4} ?#將實例對象dd使用類的屬性詳情實例化了
>>> # 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)的,類的實例對象中也會靜態(tài)存儲,所以實例對象dd正常存在。
類與對象的內(nèi)置函數(shù)
issubclass
功能:測試一個類是否是另外一個類的子類
issubclass(class, classinfo)
(1) 一個類被認為是其自身的子類
(2) classinfo可以是類對象的元組,只要class屬于其中任何一個候選類的子類,則返回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
功能:測試一個對象是否是一個類的實例對象
isinstance(object, classinfo)
(1) object為類的實例對象,如果不是類的實例對象,永遠返回False
(2) 如果第二個參數(shù)不是類或者由類對象組成的元組,會拋出一個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對象是否在A/B/C里面,答案是True
True
hasattr
功能:測試一個對象里面是否有指定的屬性
hasattr(object, name)
(1) object 對象名, name 是屬性名(需要用引號引起來,否則報錯)
getattr
功能:返回對象指定的屬性值
getattr(object, name[, default])
(1) 如果屬性值不存在打印default,沒有default則拋出異常
setattr
功能:設(shè)置對象中指定屬性的值,如果屬性不存在則創(chuàng)建并賦值
setattr(object, name, value)
delattr
功能:刪除對象中指定的屬性,如果屬性不存在則拋出異常
delattr(object, name)
舉例:
>>> class C:
def __init__(self, x=0):
self.x = x
>>> c1 = C()
>>> hasattr(c1, 'x') ?#測試對象屬性是否存在
True
>>> hasattr(c1, x)\
NameError: name 'x' is not defined
>>> getattr(c1, 'x') ?#獲取對象屬性的值
0
>>> getattr(c1, 'y')
AttributeError: 'C' object has no attribute 'y'
>>> getattr(c1, 'y', '您所訪問的屬性不存在!') ?#設(shè)置default默認提示語
'您所訪問的屬性不存在!'
>>> setattr(c1, 'y', 100) ?#設(shè)置對象屬性的值
>>> getattr(c1, 'y')
100
>>> delattr(c1, 'y') ?#刪除對象屬性的值
>>> delattr(c1, 'y')
Traceback (most recent call last):
? File "<pyshell#264>", line 1, in <module>
? ? delattr(c1, 'y')
AttributeError: y
property
功能:設(shè)置一個定義好的屬性,通過對象屬性來設(shè)置對象屬性
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)系,刪除其中一個另一個即不能訪問
AttributeError: 'C' object has no attribute 'size'
20丶魔法方法 magic methods
(1) 魔法方法總是被雙下劃綫包圍,如 __init__
(2) 魔法方法是面向?qū)ο蟮膒ython的一切
(3) 魔法方法的魔力體現(xiàn)在能夠在適當(dāng)?shù)臅r候被調(diào)用
魔法方法匯總:http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
__init__(self[, ...])
功能:初始化類對象(根據(jù)需求決定是否增加屬性參數(shù))
返回值: None
舉例:
>>> class Rectangle: #矩形類,需要長和寬,所以重寫__init__
def __init__(self, x, y):
self.x = x
self.y = y
def getPeri(self): ?#獲得周長
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)建一個類對象
返回值:返回一個對象
(1) 在__init__方法之前被調(diào)用,屬于類創(chuàng)建時第一個被調(diào)用的方法
舉例:
>>> class CapStr(str): ?#繼承一個不可改變的類型str
def __new__(cls, string): ?#使用new將類型的功能進行轉(zhuǎn)換
string = string.upper()
return str.__new__(cls, string) ?#把重寫后的str中的new方法帶傳代餐返回
>>> a = CapStr("I love M.")
>>> a
'I LOVE M.'
__del__(self)
功能:對象將要被銷毀的時候,自動調(diào)用,屬于自動垃圾回收方法
注意: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 ?#對象的賦值不會調(diào)用__init__
>>> c3 = c2
>>> del c3
>>> del c2
>>> del c1 ? #其他的賦值對象del時不會調(diào)用__del__ (c2和c3只是c1的一份拷貝)
我是del方法,我被調(diào)用了!
算術(shù)運算魔法方法
__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)用時的行為
__pow__(self, other[, modulo]) power()調(diào)用或 ** 運算時的行為
__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
類定制的計時器
(1) 定制一個計時器的類
(2) start和stop方法代表啟動計時和停止計時
(3) 假設(shè)計時器對象t1,print(t1)和直接調(diào)用t1均顯示結(jié)果
(4) 當(dāng)計時器未啟動或已經(jīng)停止計時,調(diào)用stop方法會給與溫馨的提示
(5) 兩個計時器對象可以進行相加:t1 + t2
需要的資源:
(1) 使用time模塊的localtime方法獲取時間
(2) __str__ 方法 __repr__ 方法可用來打印文字
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)
類定制計時器代碼:http://blog.csdn.net/sinat_36184075/article/details/77806778
屬性訪問
__getattribute__(self, name) #定義當(dāng)該類的屬性被訪問時的行為
__getattr__(self, name) #定義當(dāng)用戶試圖獲取一個不存在的屬性時的行為
__setattr__(self, name, value) #定義當(dāng)一個屬性被設(shè)置(包括初始化)時的行為
__delattr__(self, name) #定義一個屬性被刪除時的行為
舉例:
>>> 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 ?#初始化時自動調(diào)用setattr
>>> c.x
getattribute
1
>>> del c.x
delattr
舉例:屬性訪問時的嚴重問題,無限遞歸
class Rectangle: ?#矩形
? ? def __init__(self, width=0, height=0): ?#寬高不相等,長方形
? ? ? ? self.width = width
? ? ? ? self.height = height
? ? def __setattr__(self, name, value):
? ? ? ? if name == 'square': ?#寬高相等,正方形
? ? ? ? ? ? self.width = value
? ? ? ? ? ? self.height = value
? ? ? ? else:
? ? ? ? ? ? #self.name = value ? #會導(dǎo)致類無限遞歸自己
? ? ? ? ? ? super().__setattr__(name, value) ?#解決辦法①:super() 推薦。
? ? ? ? ? ? #self.__dict__[name] = value ? ? ?#解決辦法②:字典
? ? def getArea(self):
? ? ? ? return self.width * self.height
運行:
>>> 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
描述符就是將某種特殊類型的類的實例指派給另一個類的屬性。
__get__(self, instance, owner) ?#用于訪問屬性,返回屬性的值
__set__(self, instance, value) ?#將在屬性分配操作中調(diào)用,不反悔任何內(nèi)容
__delete__(self, instance) ? ?#控制刪除操作,不返回任何內(nèi)容
@self, 描述符類本身的類實例
@instance, 擁有者的類實例
@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() ? #實例化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擁有者的實例對象
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)換
定義一個溫度類,然后定義兩個描述符類用于描述攝氏度和華氏度兩個屬性。
要求兩個屬性會自動進行轉(zhuǎn)換,也就是說可以給攝氏度這個屬性賦值,打印華氏度是自動轉(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在實例對象中被賦值時調(diào)用對應(yīng)類的__set__
運行:
>>> 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í):
編寫一個不可改變的自定義列表,要求記錄列表中每個元素被訪問的次數(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]
運行:
>>> c1 = CountList(1, 3, 5, 7, 9)
>>> c2 = CountList(2, 4, 6, 7, 10)
>>> c1[1] ?#c1[1] == 3被訪問1次
3
>>> c2[1]
4
>>> c1[1] + c2[1] ?#c1[1] == 3被訪問2次
7
>>> c1.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c1[1] ?#c1[1] == 3被訪問3次
3
>>> c1.count
{0: 0, 1: 3, 2: 0, 3: 0, 4: 0}
迭代器 iter-next
iter
iter() 內(nèi)置方法, 功能:返回一個迭代器對象
__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 u a n . j i a n g?
斐波那契數(shù)列迭代器
>>> class Fibs: ?#斐波那契數(shù)列
def __init__(self, n=10): ? ?#加一個參數(shù)n控制迭代范圍
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self ?#本身就是一個迭代器
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é)同程序:可以運行的對立函數(shù)調(diào)用,函數(shù)可以暫停或掛起,并再需要的時候從程序離開的地方繼續(xù)活著重新開始。
舉例:
>>> 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)自動檢測迭代器的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}
#沒有字符串推導(dǎo)式,引號內(nèi)的強制解釋為字符串
>>> e = (i for i in range(10)) ?#沒有元組推導(dǎ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
生成器擴展閱讀:
http://bbs.fishc.com/forum.php?mod=viewthread&tid=56023&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
21丶模塊 module
容器 -> 數(shù)據(jù)的封裝
函數(shù) -> 語句的封裝
類 ? -> 方法和屬性的封裝
模塊 -> 程序的封裝,其實就是.py的python程序
(1) import導(dǎo)入的.py模塊文件必須放在與python.exe同一目錄下,即可正確導(dǎo)入。
(2) 導(dǎo)入方法有三種:
① import 模塊名
② from 模塊名 import 函數(shù)名1, 函數(shù)名2, ... ?#不建議這樣用,可能會覆蓋系統(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))
運行calc.py:
=================== RESTART: C:\python\test_module\calc.py ===================
32攝氏度 = 89.6華氏度
99華氏度 = 37.2攝氏度
>>>?
__name__
if __name__ = '__main__': ?#決定是.py文件中的代碼是當(dāng)前程序運行,還是導(dǎo)入到其他程序中作為模塊使用而運行
作用:限制為自身.py程序運行才執(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進去
>>> 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)建一個文件夾,用于存放相關(guān)的模塊,文件夾的名字即包(package)的名字
(2) 在文件夾中創(chuàng)建一個 __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運行時將其解釋為包
#calc.py中修改為:包名.模塊名
import M1.TemperatureConversion as tc
print('32攝氏度 = %.1f華氏度' % tc.c2f(32))
print('99華氏度 = %.1f攝氏度' % tc.f2c(99))
自帶電池:python標準庫
(1) 電池:python-IDLE 幫助文檔 F1
(2) 來自全球開發(fā)者貢獻的python模塊:https://pypi.python.org/pypi
#也可以自己寫模塊發(fā)布上去。
(3) PEP:python增強建議書,規(guī)范與定義python各種加強和延伸功能的技術(shù)規(guī)格,即參考標準
(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實例:網(wǎng)絡(luò)爬蟲
python訪問網(wǎng)絡(luò): urllib (是個包模塊)
URL一般格式:
protocol://hostname[:port]/path/[;parameters][?query]#fragment
URL三部分組成:
(1) 協(xié)議:http, https, ftp, file, ed2k...
(2) 域名/IP地址:如http默認端口號80
(3) 資源具體地址:如目錄或文件名
查看幫助文檔后發(fā)現(xiàn)urllib包有4個模塊:
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' ?#整個網(wǎng)頁的二進制文件以16進制顯示
>>> html = html.decode('utf-8') ?#按其編碼方式解碼
>>> print(html)
"""
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
</body>
</html>
"""
訪問網(wǎng)頁內(nèi)容存儲本地
舉例:
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)
運行:
會生成這個文件:C:\Users\Jan\Desktop\python_study\cat_1920_1080.jpg
實現(xiàn)POST請求 - 自動翻譯機
import urllib.request as url_req
import urllib.parse ? as url_prs
import json ?#json, 輕量級的數(shù)據(jù)交換格式
while True:
? ? content = input('請輸入需要翻譯的內(nèi)容<.q退出>:')
? ? if content == '.q':
? ? ? ? break
? ? else:
? ? ? ? #注意url地址<有道翻譯>,按小甲魚視頻中的可能不對,需到網(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']))
#缺陷:能夠被識別為代碼訪問,而非瀏覽器,即非人類訪問
運行:
========= RESTART: C:\Users\Jan\Desktop\python_study\translation.py =========
請輸入需要翻譯的內(nèi)容<.q退出>:生存,還是毀滅,這是一個問題
翻譯結(jié)果:To survive, or not to be, this is a problem
請輸入需要翻譯的內(nèi)容<.q退出>:To be or not to be, it's a question.
翻譯結(jié)果:生存還是毀滅,這是一個問題。
請輸入需要翻譯的內(nèi)容<.q退出>:.q
>>>?
修改header
(1) 通過Request的headers參數(shù)修改,字典形式
(2) 通過Request.add_header()方法修改
追加header模擬瀏覽器訪問:
import urllib.request as url_req
import urllib.parse ? as url_prs
import json ?#json, 輕量級的數(shù)據(jù)交換格式
while True:
? ? content = input('請輸入需要翻譯的內(nèi)容<.q退出>:')
? ? if content == '.q':
? ? ? ? break
? ? else:
? ? ? ? #注意url地址,視頻中的可能不對需到網(wǎng)上查
? ? ? ? url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http://www.youdao.com/'
? ? ? ? #header方法1:創(chuàng)建字典,請求中傳參
? ? ? ? '''
? ? ? ? head = {} ?#模擬瀏覽器訪問 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)用請求的方法:data, head '''
? ? ? ? #header方法2:請求中追加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']))
運行:
========= RESTART: C:\Users\Jan\Desktop\python_study\translation.py =========
請輸入需要翻譯的內(nèi)容<.q退出>:生存,還是毀滅,這是一個問題
翻譯結(jié)果:To survive, or not to be, this is a problem
請輸入需要翻譯的內(nèi)容<.q退出>:To be or not to be, it's a question.
翻譯結(jié)果:生存還是毀滅,這是一個問題。
請輸入需要翻譯的內(nèi)容<.q退出>:.q
>>>?
代理
作用:讓爬蟲偽裝瀏覽器請求,讓http服務(wù)器不會認為是非人類訪問。
步驟:
(1) 參數(shù)是一個字典{'類型':'代理ip:端口號'}
proxy_support = urllib.request.ProxyHandler({})
(2) 定制、創(chuàng)建一個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' ?#這個網(wǎng)站訪問它會顯示自己的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隨機取ip
#網(wǎng)上查的免費代理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)
補充:
Beautiful Soup 是用Python寫的一個HTML/XML的解析器,使用安裝python-IDLE時附帶的pip命令,直接在windows下執(zhí)行:
C:\python> pip install bs4
#一鍵安裝搞定,python中測試能否導(dǎo)入成功
>>> from bs4 import BeautifulSoup
>>> #成功導(dǎo)入,失敗會報異常。
采集代理ip
import urllib.request as url_req
from bs4 import BeautifulSoup ?#此庫需要安裝:win-cmd執(zhí)行"pip install bs4"即可
import random
import pprint as ppr
#這個網(wǎng)站訪問它會顯示自己的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頁
? ? ? ? ? ? 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()搜索解析器解析出來的html文檔樹
? ? ? ? ? ? for x in range(1, len(ips)):
? ? ? ? ? ? ? ? ip = ips[x]
? ? ? ? ? ? ? ? tds = ip.findAll('td') ?#ip和端口都在tr標簽中的td標簽中
? ? ? ? ? ? ? ? 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}) ?#從列表中隨機選擇代理ip和端口項
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)
運行:
======== 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>真實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) #打開一個鏈接,參數(shù)可以是一個字符串或者Request對象
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爬蟲下載妹子圖
代碼:#代理ip不太穩(wěn)定,免費代理很多時好時壞
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
#打開url接口函數(shù)
def url_open(url):
? ? req = urllib.request.Request(url)
? ? req.add_header(header_key, header_value)
? ? '''
? ? #使用代理模擬真人訪問而不是代碼訪問
? ? 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位置開始找到一個]符號
? ? 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位置開始,以 .jpg 結(jié)尾的地方
? ? ? ? if b != -1: ?#find找不到時返回-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開始
? ? #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取最后一個元素
? ? ? ? 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/' ?#實際圖源來源于新浪服務(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----------------------------------------
正則表達式
"我知道,可以使用正則表達式解決現(xiàn)在遇到的難題。"于是,現(xiàn)在他就有兩個問題了。
>>> import re
>>> re.search(r'Hello', 'I love you, Hello!~') ?#search()方法用于在字符串中搜索正則表達式模式第一次出現(xiàn)的位置
<_sre.SRE_Match object; span=(12, 17), match='Hello'> ?#第12-16個字符位置
>>> re.search(r'lo', 'hello')
<_sre.SRE_Match object; span=(3, 5), match='lo'>
>>> 'hello'.find('lo')
3
#.點號:匹配除了換行符的任何字符
>>> re.search(r'.', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(0, 1), match='I'>
#匹配點號本身,使用\反斜杠轉(zhuǎn)義即可
>>> re.search(r'\.', 'I love you, baidu.com!~')
<_sre.SRE_Match object; span=(17, 18), match='.'>
#\d表示匹配一個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') #無法匹配,位數(shù)不同
#使用[]創(chuàng)建一個字符類
>>> 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'>
#{}大括號:來限定匹配的次數(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') ?#錯誤示范
>>> re.search(r'[0-255]', '188') ?#0,1,2,5其中任何一個,匹配
<_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正則表達式
<_sre.SRE_Match object; span=(0, 3), match='188'>
#ip地址正則表達式
>>> 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表達式的一點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地址匹配的正則表達式【嚴謹版】
import re
ptnIP = re.compile(r'(?<![\d.])' # 前導(dǎo) 無 數(shù)字和小數(shù)點
? ? ? ? ? ? ? ? ? ?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ù) 無 數(shù)字和小數(shù)點
? ? ? ? ? ? ? ? ? )
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)
運行:
========== 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 正則表達式特殊符號及用法(詳細列表)
http://blog.csdn.net/riba2534/article/details/54288552
正則表達式舉例:
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)' ?# 正則表達式匹配貼吧圖片鏈接
? ? imglist = re.findall(p, html) ?# findall中的p包含子組()的話,會單獨返回子組
? ? # 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))
運行:
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) 無 數(shù)字和小數(shù)點
? ? ? ? ? ? ?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ù) 無 數(shù)字和小數(shù)點
? ? iplist = re.findall(ptnIP, html) ?# findall中的p包含子組()的話,會單獨返回子組
? ? # 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') ?#打開一個不存在的鏈接
>>> try:
urllib.request.urlopen(req)
except urllib.error.URLError as e:
print(e.reason)
[Errno 11001] getaddrinfo failed ?#錯誤信息
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'
處理異常的寫法:
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爬蟲框架
① Scrapy的安裝與環(huán)境搭建
Scrapy對應(yīng)python2.7的版本。(安裝過程中如遇任何問題均可百度搜索一下,這是程序員必須學(xué)會的快速解決問題的辦法)
1. 安裝python2.7(32位版本)
安裝包:python-2.7.6-win32.msi
設(shè)置環(huán)境變量:win-運行-cmd
> C:\Python27\python.exe C:\Python27\tools\Scripts\win_add2path.py
重啟windows系統(tǒng),驗證安裝是否成功:
> python --version
#如果顯示是3.多的版本,請參考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),驗證安裝是否成功:
> pip --version
#如果沒有顯示版本信息,請參考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
驗證是否安裝成功:
> Scrapy
#如果提示找不到命令的話,可能需要一個工具環(huán)境支持:Twisted-15.0.0.win32-py2.7.msi
安裝完Twisted后再次嘗試驗證即可。
② Scrapy框架爬蟲程序初探
一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。最初是為了頁面抓取所設(shè)計的,也可以應(yīng)用在獲取API所訪問的數(shù)據(jù)上,或者說通用的網(wǎng)絡(luò)爬蟲上。
使用Scrapy抓取一個網(wǎng)站一共需要四個步驟:
1. 創(chuàng)建一個Scrapy項目;
2. 定義Item容器;
3. 編寫爬蟲;
4. 存儲內(nèi)容。
---Scrapy框架(官網(wǎng))圖示---
實驗網(wǎng)站對象:www.dmoz.org
1. 創(chuàng)建一個Scrapy項目:crawler
C:\Users\Jan\Desktop\python_study>Scrapy startproject crawler
#crawler是我們的項目名稱
在\python_study\crawler\文件夾中即是我們的爬蟲框架。
Item是保存爬取到的數(shù)據(jù)的容器,其使用方法和python字典類似,并且提供了額外保護機制來避免拼寫錯誤導(dǎo)致的未定義字段錯誤。
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. 編寫爬蟲:
編寫爬蟲類Spider,Spider是用戶編寫用于從網(wǎng)站上爬取數(shù)據(jù)的類。其包含了一個用于下載的初始化URL,然后是如何跟進網(wǎng)頁中的鏈接以及如何分析頁面中的內(nèi)容,還有提取生成item的方法。
#crawler\crawler\spiders\crawler_spider.py 新建文件
import scrapy
class CrawlerSpider(scrapy.Spider):
? ? name = 'csdn' ?#爬蟲名字,調(diào)用的時候使用
? ? 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爬蟲類中的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: 我們的目標爬取鏈接
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)容存儲位置(爬取網(wǎng)站的源碼文件):
C:\Users\Jan\Desktop\python_study\crawler\ 目錄下 geek.csdn.net 的NET文件。
3.2 取
在Scrapy中使用的是一種基于XPath和CSS的表達式機制:Scrapy Selectors(選擇器)
Selector是一個選擇器,有4個基本方法:
xpath() 傳入xpath表達式,返回該表達式所對應(yīng)的所有節(jié)點的selector list列表。
css() 傳入CSS表達式,返回該表達式所對應(yīng)的所有節(jié)點的selector list列表。
extract() 序列化該節(jié)點為unicode字符串并返回list。
re() 根據(jù)傳入的正則表達式對數(shù)據(jù)進行提取,返回unicode字符串list列表。
win-cmd進入項目根目錄后執(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)頁的源碼信息
>>> response.headers ?#輸出網(wǎng)頁的頭部信息
{'Date': ['Fri, 08 Sep 2017 14:06:31 GMT'], 'Content-Type': ['text/html; charset=utf-8'], 'Server': ['openresty'], 'Vary': ['Accept-Encoding', 'Accept-Encoding']}
XPath是一門在網(wǎng)頁中查找特定信息的語言,所以用XPath來篩選數(shù)據(jù),要比使用正則表達式容易些。
/html/head/title 選擇HTML文檔中<head>標簽內(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>標簽的內(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>標簽中的字符串,即標題
>>> sel.xpath('//span/a/@href').extract() ?#獲取<span><a>中的連接地址
>>> sites = sel.xpath('//div/div/div/dl/dd/span/a/text()').extract() ?#按照標簽包裹的層級<body>下開始找到包裹標題的<a>標簽寫入xpath中
>>> for title in sites: ?#使用for循環(huán)打印可以自動將Unicode轉(zhuǎn)換為對應(yīng)中文編碼顯示
... ? ? print(title)
自己動手做聊天機器人 四十二-(重量級長文)從理論到實踐開發(fā)自己的聊天機器人
微軟攜手 Facebook 推出開源項目 打造共享神經(jīng)網(wǎng)絡(luò)模型
Taylor Swift vs 人工智能:作詞誰更強?
推薦13個機器學(xué)習(xí)框架
...
>>> sites = sel.xpath('//div/div/div[@class="directory-url"]/dl/dd/span/a/text()').extract()
#其中[@class="directory-url"]的功能是:過濾掉對應(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
#運行就可以將print中的內(nèi)容在爬取時一并顯示出來(輸出內(nèi)容略)
4. 存儲內(nèi)容
最常見的導(dǎo)出為json格式。
中文亂碼問題:http://bbs.fishc.com/thread-85672-1-1.html
#crawler\crawler\spiders\crawler_spider.py ?構(gòu)造items的列表對象
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() ?#實例化一個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)容存儲的文件名以及校正中文亂碼
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' ?#這一句會將你每次返回的字典抓取出來,“ensure_ascii=False”這一句話很重要,如果是True的話就是我們保存的\u4e2d\u56fd這種格式了
? ? ? ? self.file.write(line) ?#寫入到文件中
? ? ? ? return item
#crawler\crawler\setting.py ?使pipelines.py生效,取消注釋ITEM_PIPELINES
ITEM_PIPELINES = {
? ? 'crawler.pipelines.CrawlerPipeline': 300, ?#300是正常值,不變。
}
win-cmd運行scrapy,即可自動在\crawler\目錄下生成items.json文件,并且中文顯示正常:
C:\Users\Jan\Desktop\python_study\crawler>scrapy crawl csdn
C:\Users\Jan\Desktop\python_study\crawler\items.json ?#中文正常。
{"title": ["自己動手做聊天機器人 四十二-(重量級長文)從理論到實踐開發(fā)自己的聊天機器人"], "link": ["http://www.shareditor.com/blogshow?blogId=136&hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
{"title": ["微軟攜手 Facebook 推出開源項目 打造共享神經(jīng)網(wǎng)絡(luò)模型"], "link": ["http://tech.163.com/17/0908/08/CTQ1403R00097U80.html"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
{"title": ["Taylor Swift vs 人工智能:作詞誰更強?"], "link": ["http://dataquestion.com/taylor-vs-ai"], "desc": ["\n ? ? ? ? ? ? ? ? ? ? ? ? ? ?", "\n ? ? ? ? ? ? ? ? ? ? ? ?"]}
...
--------------------------------2017.09.09----------------------------------------
23丶GUI界面的終極選擇 Tkinter
Tkinter是python的默認GUI模塊庫。
示例1:主窗口及標題
import tkinter as tk
app = tk.Tk() ?#根窗口的實例(root窗口)
app.title('Tkinter root window') ?#根窗口標題
theLabel = tk.Label(app, text='我的第2個窗口程序!') ?#label組件及文字內(nèi)容
theLabel.pack() ?#pack()用于自動調(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('臥槽,居然打了個招呼!~')
root = tk.Tk()
app = APP(root)
root.mainloop()
示例3:圖片
from tkinter import *
root = Tk()
textLabel = Label(root,
? ? ? ? ? ? ? ? ? text='請重試!\n您的操作不被允許!', ?#文字支持換行
? ? ? ? ? ? ? ? ? justify=LEFT, ?#左對齊
? ? ? ? ? ? ? ? ? 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這是一個問題',
? ? ? ? ? ? ? ? ?justify=LEFT,
? ? ? ? ? ? ? ? ?image=photo,
? ? ? ? ? ? ? ? ?compound=CENTER,
? ? ? ? ? ? ? ? ?font=('華文隸書', 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('請重試!\n您的操作不被允許!')
textLabel = Label(frame1,
? ? ? ? ? ? ? ? ? textvariable=var,
? ? ? ? ? ? ? ? ? justify=LEFT) ?#左對齊
textLabel.pack(side=LEFT)
#顯示圖片
photo = PhotoImage(file='tk_image.png')
imageLabel = Label(root, image=photo)
imageLabel.pack(side=RIGHT)
theButton = Button(frame2, text='我是超級管理員', command=callback)
theButton.pack()
frame1.pack(padx=10, pady=10)
frame2.pack(padx=10, pady=10)
mainloop()
示例6:選項按鈕
from tkinter import *
root = Tk()
v = IntVar()
c = Checkbutton(root, text='測試一下', variable=v) ?#v用來存放選中狀態(tài)
c.pack()
l = Label(root, textvariable=v)
l.pack() ?#未選中顯示為0,選中顯示1
mainloop()
示例7:多個方框選項
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è)置對齊方位,東E南S西W北N
mainloop()
示例8:多個圓點選項 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)陷填充按鈕選項 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: ?#對應(yīng)列表中包含元組同時執(zhí)行多個循環(huán)
? ? b = Radiobutton(root, text=lang, variable=v, value=num, indicatoron=False)
? ? b.pack(fill=X)
mainloop()
示例10:附帶標題的圓點選項 LabelFrame
from tkinter import *
root = Tk()
group = LabelFrame(root, text='最好的開發(fā)語言是?', 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: ?#對應(yīng)列表中包含元組同時執(zhí)行多個循環(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, '默認文本...')
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)容時點擊獲取信息會打印
? ? 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='點擊退出', width=10, command=root.quit) \
? ? ? ? ? ? ?.grid(row=3, column=1, sticky=E, padx=10, pady=5)
#退出按鈕必須是雙擊打開.py文件才可以,而不是在IDLE下調(diào)試運行時
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)
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('賬號:%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='點擊退出', width=10, command=root.quit) \
? ? ? ? ? ? ?.grid(row=3, column=1, sticky=E, padx=10, pady=5)
#退出按鈕必須是雙擊打開.py文件才可以,而不是在IDLE下調(diào)試運行時
mainloop()
示例13:輸入對錯驗證程序
from tkinter import *
root = Tk()
root.title('輸入對錯驗證')
def test():
? ? if e1.get() == '張三':
? ? ? ? print('正確!')
? ? ? ? return True
? ? else:
? ? ? ? print('錯誤!')
? ? ? ? e1.delete(0, END)
? ? ? ? return False
v = StringVar()
#focusout指定在當(dāng)前輸入框失去焦點時,代表輸入完,會去調(diào)用test校驗<tab>鍵可測試
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:簡單計算器程序
from tkinter import *
root = Tk()
root.title('計算器程序')
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ào)用test校驗<tab>鍵可測試
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='計算結(jié)果', command=calc).grid(row=1, column=2, pady=5)
mainloop()
示例14:按鈕刪除列表中的選項
from tkinter import *
master= Tk()
theLB = Listbox(master, selectmode=SINGLE, height=15) ?#SINGLE單選,MULTIPLE多選,height設(shè)置顯示項數(shù)
theLB.pack()
for item in ['筆', '墨', '紙', '硯']:
? ? theLB.insert(END, item) ?#END表示最后一個
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:為列表組件添加滾動條
安裝垂直滾動條步驟:
1) 設(shè)置該組件的yscrollbarcommand選項為Scrollbar組件的set方法;
2) 設(shè)置Scrollbar組件的command選項為該組件的yview()方法。
from tkinter import *
root = Tk()
root.title('滾動條程序')
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)
#讓滾動條與選項互通互連
sb.config(command=lb.yview)
mainloop()
示例16:滑塊滾動條 Scale
from tkinter import *
root = Tk()
root.title('滑塊程序')
s1 = Scale(root, from_=0, to=100, tickinterval=5, resolution=5, length=200) ?#默認是垂直, 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)前位置,點擊后才有效
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表示輸入光標插入的位置
text.insert(END, '對比一下效果。')
def show():
? ? print('提交中...') ?#此行內(nèi)容顯示在IDLE中
#插入一個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)
#插入一個圖片
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') ?#文字會以red為準
mainloop()
示例20:文本組件中可點擊連接
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>鼠標進入
text.tag_bind('link', '<Leave>', show_xterm_cursor) ?#<Enter>鼠標離開
text.tag_bind('link', '<Button-1>', click) ?#<Enter>鼠標點擊
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('無任何修改!')
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' ?#開頭的位置,第1行的第0個下標位置
while True:
? ? pos = text.search('o', start, stopindex=END) ?#查找文本中字符o的位置
? ? if not pos:
? ? ? ? break
? ? print('找到啦,位置是:', getIndex(text, pos))
? ? start = pos + '+1c' ?#'+1c'指向下一個字符
mainloop()
示例23:文本組件之撤銷操作
from tkinter import *
root = Tk()
root.title('link click')
text = Text(root, width=50, height=10, undo=True) ?#undo模式開啟
text.pack()
text.insert(INSERT, 'I love www.baidu.com')
def show():
? ? text.edit_undo()
Button(root, text='撤銷', command=show).pack() ?#多次撤銷會刪除文本組件內(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')
#藍色的豎虛線
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) ?#移動位置
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') ?#橢圓是通過限定矩形的方式畫出來,圓形通過正方形
#w.create_oval(60, 30, 300, 270, fill='pink') ?#正方形對應(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 = [
? ? #左上點
? ? center_x - int(r * m.sin(2 * m.pi / 5)),
? ? center_y - int(r * m.cos(2 * m.pi / 5)),
? ? #右上點
? ? center_x + int(r * m.sin(2 * m.pi / 5)),
? ? center_y - int(r * m.cos(2 * m.pi / 5)),
? ? #左下點
? ? center_x - int(r * m.sin(m.pi / 5)),
? ? center_y + int(r * m.cos(m.pi / 5)),
? ? #頂點
? ? center_x,
? ? center_y - r,
? ? #右下點
? ? 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 (自定義畫板)
#繪制一個極小的圓來代表一個點(tkinter本身不支持畫點)
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>綁定鼠標左鍵事件
Label(root, text='按住鼠標左鍵并移動,開始繪制吧!~~').pack(side=BOTTOM)
mainloop()
示例30:菜單組件 Menu (主菜單/下拉菜單/右鍵菜單/單多選菜單/按鈕菜單/選項菜單(列表))
from tkinter import *
root = Tk()
root.title('Main Menu Show')
def callback():
? ? print('你好~')
menubar = Menu(root)
#注冊菜單:文件(下拉菜單)
filemenu = Menu(menubar, tearoff=False) ?#來自主菜單,tearoff參數(shù)可讓菜單窗口分離
filemenu.add_command(label='新建', command=callback)
filemenu.add_command(label='打開...', 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) ?#來自主菜單
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='多選項1', command=callback, variable=openVar)
optionmenu.add_checkbutton(label='多選項2', command=callback, variable=saveVar)
optionmenu.add_checkbutton(label='多選項3', command=callback, variable=quitVar)
menubar.add_cascade(label='選項(C)', menu=optionmenu)
#主菜單:單選√ radiobutton(下拉菜單)
otherVar = IntVar()
othermenu = Menu(menubar, tearoff=False)
othermenu.add_radiobutton(label='單選項1', command=callback, variable=otherVar, value=1)
othermenu.add_radiobutton(label='單選項2', command=callback, variable=otherVar, value=2)
othermenu.add_radiobutton(label='單選項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)部菜單:選項菜單 OptionMenu
variable = StringVar()
variable.set('one') ?#默認顯示one
w = OptionMenu(root, variable, 'one', 'two', 'three')
w.pack()
#將列表添加到選項菜單 OptionMenu
OPTIONS = [
? ? '表項1',
? ? '對比2',
? ? '選項3',
? ? '其他4',
? ? '退出5'
? ? ]
var = StringVar()
var.set(OPTIONS[0])
o = OptionMenu(root, var, *OPTIONS) ?#*星號解包可變參數(shù)列表為逐個元素
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為鼠標右鍵,1為左鍵,2為中鍵
root.config(menu=menubar) ?#menu參數(shù)會將菜單設(shè)置添加到root根窗口
mainloop()
示例31:事件綁定 bind (鼠標/按鍵/按鍵組合)
from tkinter import *
root = Tk()
root.title('Event bind')
frame = Frame(root, width=200, height=200)
#鼠標響應(yīng)事件
def callback1(event): ?#event形參獲取事件描述,必備參數(shù)
? ? print('點擊位置:', event.x, event.y)
frame.bind('<Button-1>', callback1) ?#Button表示鼠標點擊事件, 12345分別代表左中右鍵上滾下滾
frame.pack()
#鍵盤響應(yīng)事件
def callback2(event):
? ? print(event.keysym) ?#打印信息在IDLE, keysym指鍵盤所有按鍵
frame.bind('<Key>', callback2)
frame.focus_set()
frame.pack()
#鼠標即時響應(yīng)事件
def callback3(event):
? ? print('點擊位置:', event.x, event.y)
frame.bind('<Motion>', callback3) ?#鼠標在窗口內(nèi)只要有移動就一直輸出位置
frame.pack()
#事件序列(按鍵組合),語法:<modifier-type-detail> 如
#點擊鼠標左鍵:<Button-1> ?ButtonRelease更安全,移除組件釋放點擊時不去觸發(fā)
#點擊H字母按鍵:<KeyPress-H>
#同時點擊Ctrl+Shift+H:<Control-Shift-KeyPress-H>
mainloop()
示例32:消息組件 Message | 輸入組件 Spinbox
from tkinter import *
root = Tk()
root.title('Module')
#消息組件:Message
m1 = Message(root, text='這是一個消息:', width=100)
m1.pack()
m2 = Message(root, text='這是一\n則駭人聽聞的長長長長長長長消息!', 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)
'''
#三窗格,同時顯示隱藏布局線(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)建頂級窗口,即彈出窗口)
from tkinter import *
root = Tk()
root.title('Toplevel')
def create():
? ? top = Toplevel()
? ? #top.attributes('-alpha', 0.5) 設(shè)置彈出的頂級窗口透明度:50%
? ? top.title('Toplevel demo...')
? ? msg = Message(top, text='I love python...')
? ? msg.pack()
Button(root, text='創(chuàng)建頂級窗口', command=create).pack() ?#點擊出現(xiàn)頂級窗口
mainloop()
示例35:幾何管理類,包pack(),網(wǎng)格grid(),位置place()
#pack() ?注意pack和grid不要混合使用
from tkinter import *
root = Tk()
root.title('pack')
#Listbox完全填充測試
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')
#兩個sticky=W實現(xiàn)第一列左對齊
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() ? 可以實現(xiàn)一些pack和grid實現(xiàn)不了的布局
from tkinter import *
root = Tk()
root.title('place')
#place位置布局測試
'''
photo = PhotoImage(file='tk_image.png')
Label(root, image=photo).pack() ?#按鈕就會出現(xiàn)在圖片的組件上,實現(xiàn)組件疊加顯示
def callback():
? ? print('正中靶心!!!')
#relx,rely相對父組件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:對話框 (警告 showinfo | 消息 messagebox | 文件 filedialog | 顏色 colorchooser)
from tkinter import *
from tkinter import messagebox ? ?#messagebox()需要單獨導(dǎo)入
from tkinter import filedialog ? ?#filedialog()需要單獨導(dǎo)入
from tkinter import colorchooser ?#colorchooser()需要單獨導(dǎo)入
from tkinter.messagebox import * ?#用戶使用showinfo()
#警告對話框
showinfo(title='test', message='警告')
#消息對話框
result = messagebox.askokcancel('demo', '發(fā)射核彈?') ?#返回值是True或False
print(result) ?#根據(jù)用戶按下了確定還是取消做進一步的操作
#文件對話框
root = Tk()
def callback1():
? ? filename = filedialog.askopenfilename(defaultextension='.py') ?#指定文件后綴
? ? print(filename) ?#返回的是文件的完整路徑
Button(root, text='打開文件', command=callback1).pack()
#顏色選擇對話框
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的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jedis 设置key的超时时间
- 下一篇: Host SMBus controlle