python bif_小猪的Python学习之旅 —— 1.基础知识储备
引言:(文章比較長(zhǎng),建議看目錄按需學(xué)習(xí)~)
以前剛學(xué)編程的時(shí)候就對(duì)Python略有耳聞,不過學(xué)校只有C,C++,Java,C#。
和PHP有句"PHP是最好的語言" 這種家喻戶曉的騷話一樣,Python也有
"人生苦短,我用Python"。而接觸Python這個(gè)詞最多的場(chǎng)合就是在一些技術(shù)群里,
有些大佬張嘴動(dòng)不動(dòng)就說什么Py交易,作為潛伏在群里的開發(fā)萌新的我每次都
會(huì)忍不住會(huì)發(fā)出這樣的感慨:
而真正接觸了下Python是在上家公司,當(dāng)時(shí)老大讓我寫個(gè)腳本去下載
倉庫里最近打包的apk,當(dāng)時(shí)東湊湊西湊湊最后總算拼成了一個(gè)可運(yùn)行
的py文件,因?yàn)椴涣私釶ython里的數(shù)據(jù)結(jié)構(gòu),全部用的字符串變量,
后面被老大教育了一番才知道有元組這種東西。因?yàn)楸旧碜鯝ndroid的,
Python用到的場(chǎng)合不多,加之覺得Kotlin有點(diǎn)意思,就沒去研究Python了。
前段時(shí)間,手頭的事做得差不多了,無聊四處張望時(shí),看到隔壁后臺(tái)
小哥迅雷瘋狂下載東西,建文件夾,粘貼復(fù)制,不知道還以為他在給
小電影分類呢,后來一問才知道,運(yùn)營(yíng)讓他把服務(wù)器上所有的音頻
文件下下來,然后根據(jù)對(duì)應(yīng)的類別下到對(duì)應(yīng)文件夾,所以他做的事情
就是:迅雷批量下載過歌曲 -> 看mysql歌曲的分組 -> 建文件夾
-> 粘貼復(fù)制歌曲到這個(gè)文件夾下,咋一看,流程挺簡(jiǎn)單的,然而有
4700多首歌,幾百個(gè)目錄,這樣慢慢搞怕是要搞幾天,而且常時(shí)間
機(jī)械化的重復(fù)某項(xiàng)工作,很容易出錯(cuò)。看著一臉絕望的后臺(tái)小哥:
于心不忍,決定寫個(gè)py腳本來拯救他,腦子里也有了程序的大概邏輯:
1.讓后臺(tái)導(dǎo)出一份mysql建表語句,安裝mysql把表建起來;
2.Python連mysql,讀取表里的數(shù)據(jù)
3.編寫帶limit去重的sql查詢語句,查詢得到所有分類
4.得到的所有分類就是要?jiǎng)?chuàng)建的文件夾,迭代批量創(chuàng)建文件夾;
5.sql查詢歌曲下載url與分類,拼接,寫入到文件中;
6.讀取文件,迭代:下載url截取文件名與分類路徑拼接成文件
的完整路徑,調(diào)用下載相關(guān)函數(shù)下載url到對(duì)應(yīng)路徑即可。
邏輯挺簡(jiǎn)單明了的,然而各種坑,最后折騰了一天才能弄出來
遇到了下面這些問題:
1.最坑的解碼問題:默認(rèn)使用Python2,中文亂碼,各種網(wǎng)上搜,
設(shè)置編碼方式,都沒用,頭皮發(fā)麻,特別是在截取文件名的時(shí)候。
后面換了一波Python3,很舒服,什么問題都沒了。
2.沒有對(duì)異常進(jìn)行捕獲,有些資源失效404,下到中途才發(fā)現(xiàn).;
3.想弄多線程下載的,因?yàn)镻ython很多基礎(chǔ)不知道,后面放棄了;
當(dāng)看到所有文件都下載到了對(duì)應(yīng)的位置,一種油然而生的成就感,
比起寫APP天天畫界面,請(qǐng)求,解析數(shù)據(jù),顯示數(shù)據(jù),有意思太多,
畢竟學(xué)習(xí)開發(fā)興趣很重要,索性從零開始學(xué)習(xí)下Python吧,越學(xué)越覺得:
理由上班時(shí)的閑暇時(shí)間,歷時(shí)兩周總算是把基礎(chǔ)知識(shí)的東西過了
一遍,遂有此文,畢竟初學(xué)者,有些地方可能理解有誤,望看到
的大佬不吝賜教,文中大部分內(nèi)容摘自:
《Python 3 教程》與《小甲魚的零基礎(chǔ)入門學(xué)習(xí)Python》
有興趣的可以閱讀下這兩本書~
本文不是入門教程啊,完全沒有編程經(jīng)驗(yàn)的不建議閱讀!
完全小白可以看下這本:《編程小白的第一本Python入門書》
目錄
[TOC]
1.學(xué)習(xí)資源相關(guān)
API文檔
書籍
2.學(xué)習(xí)Python2還是Python3的問題
!!!Python 3的語法 不完全兼容 Python 2的語法!!!
菜逼剛學(xué)Python沒多久,不敢大聲嗶嗶,最直接原因:
Python 3默認(rèn)使用utf-8,在處理中文的時(shí)候可以
減少很多編解碼的問題,而Python 2默認(rèn)使用ascii。
另外的原因:與時(shí)俱進(jìn),IT行業(yè)發(fā)展那么迅速,完全過渡只是時(shí)間問題;
舉個(gè)例子:Android Studio剛出的沒多久的時(shí)候,各種說卡啊,垃圾,
只能開一個(gè)項(xiàng)目等各種嫌棄,不如Eclipse好用;然而現(xiàn)在開發(fā)Android
還是用Eclipse的都是會(huì)被歧視一波的,另外官方已經(jīng)確定Python 2.7會(huì)
在2020年退休。So:人生苦短,我用Python3。
而且Python 2.7預(yù)計(jì)會(huì)在2020年退休
更多比較的文章可見:
3.開發(fā)環(huán)境搭建
Python下載安裝
Windows
傻瓜式下一步就好,記得勾選Add Python x.x to Path!勾選
了你裝完就不用自己去配置環(huán)境變量,安裝完畢后打開CMD輸入:
python3 -V 能查看到安裝的Python版本說明安裝成功,
如果提示錯(cuò)誤:python3不是內(nèi)部或外部命令之類的話,恭喜你
可以百度下:Python3環(huán)境變量配置 了~
Mac
方法一:官網(wǎng)下安裝包,傻瓜下一步;
方法二:如果有裝Homebrew,終端輸入:brew install Python3 安裝即可。
Ubuntu:一般內(nèi)置,執(zhí)行下述命令可查看版本,如果想安裝自己喜歡
的版本可以鍵入:sudo apt-get install python版本號(hào) 進(jìn)行安裝
PyCharm下載安裝
其實(shí)在安裝完P(guān)ython后就可以進(jìn)行Python編程了,直接命令行輸入python3,
就可以使用自帶的IDLE進(jìn)行開發(fā)了;又或者直接用Sublime Text或NotePad++
這類代碼查看工具直接編寫代碼,然后保存成后綴為.py的文件,然后python3
執(zhí)行這個(gè)py文件就可以了。
雖然可以,但是挺不方便的,比如縮進(jìn)問題,Python通過縮進(jìn)來表示代碼塊,
代碼一多,某一行沒有正確的使用縮進(jìn),結(jié)果可能與你預(yù)期的相差甚遠(yuǎn)。
智能提示,方便的依賴庫管理等,這兩個(gè)就不用說了吧,具體的還得你自己體會(huì)。
官網(wǎng)下載:https://www.jetbrains.com/pycharm/download/
下載Professional版本,傻瓜式安裝,打開后會(huì)彈出注冊(cè)頁面,
勾選License server,在License server address輸入注冊(cè)服務(wù)器,
網(wǎng)上搜很多,然后就可以愉快的進(jìn)行py開發(fā)了。
軟件的基本使用也非常簡(jiǎn)單,Jetbrains的IDE都是差不多的~
有一點(diǎn)要注意的地方是,如果你想切換項(xiàng)目依賴的Python版本號(hào)的話:
打開設(shè)置(Preference或settings),修改即可:
4.基本常識(shí)
1) 導(dǎo)包
有時(shí)項(xiàng)目中需要引入其他模塊或者模塊中的某個(gè)函數(shù),需要用到import和
from...import,用法示例如下:
import sys # 導(dǎo)入整個(gè)模塊
from sys import argv # 導(dǎo)入模塊中的需要用到的部分
from urllib.error import URLError, HTTPError # 多個(gè)的時(shí)候可以用逗號(hào)隔開
from sys import * # 導(dǎo)出模塊中的所有
# 另外還可以使用as關(guān)鍵字為模塊設(shè)置別名,比如 import sys as s
# 調(diào)用的時(shí)候直接s.argv 這樣就可以了。
2) 關(guān)鍵字與標(biāo)識(shí)符命名規(guī)則
在對(duì)變量或者方法名這些標(biāo)識(shí)符進(jìn)行命名的時(shí)候,需要注意,不能夠
與Python中的關(guān)鍵字相同,通過keyword.kwlist可以查詢所有的關(guān)鍵字:
需要import keyword模塊哦~
除了不能與與關(guān)鍵字相同外,標(biāo)識(shí)符的命名規(guī)則:
由字母,數(shù)字和下劃線組成,且首字符必須為字母或下劃線,
Python對(duì)大小寫敏感;關(guān)于命名規(guī)范的問題,沒有什么
強(qiáng)制規(guī)定,整個(gè)項(xiàng)目保持統(tǒng)一就好,附上網(wǎng)上找的一個(gè)命名規(guī)則:
>
1.項(xiàng)目名:首字母大寫,其余小寫,用下劃線增加可讀性,如:Ui_test;
2.包名與模塊名:全部小寫字母;
3.類名:首字母大寫,其余小寫,多個(gè)單詞駝峰命名法;
4.方法(函數(shù))名:全部小寫,多個(gè)單詞用下劃線分隔;
5.參數(shù)名:小寫單詞,如果與關(guān)鍵詞沖突,參數(shù)名前加上下劃線,比如_print;
6.變量:小寫,多個(gè)單詞用下劃線分隔;
7.常量:全部大寫,多個(gè)單詞用下劃線分隔;
3) 注釋
Python 使用 # 來進(jìn)行 單行注釋,多行注釋 的話使用三引號(hào),比如:
'''
這是
Python的
多行注釋
'''
4) print打印輸出與input輸入函數(shù)
學(xué)習(xí)一門新的編程語言,第一個(gè)程序基本都是打印Hello world,
把結(jié)果打印到屏幕上,是驗(yàn)證代碼執(zhí)行結(jié)果的最直觀體現(xiàn),所以
有必要先學(xué)一波 print 和 input 的用法!
print():
1.可以輸出各種亂七八糟類型的數(shù)據(jù)直接轉(zhuǎn)成字符串打印輸出;
2.print默認(rèn)會(huì)換行,如果不換行可以: print(xxx, end = "")
3.支持 格式化輸出,和C中的printf用法類似,逗號(hào)分隔前后改成%:
input():
從鍵盤讀入一個(gè)字符串,并自動(dòng)忽略換行符,所有形式的輸入按字符串處理。
可以在括號(hào)里寫一些輸入的提示信息,比如: input("請(qǐng)輸入一個(gè)字符串:")
???輸出結(jié)果:???
5) help函數(shù)
這個(gè)就不用說了,很多編程語言都有的,可以用來查看某個(gè) 內(nèi)置函數(shù)(BIF)
的相關(guān)用法的,比如help(print),會(huì)輸出這樣的結(jié)果:
6) dir函數(shù)
查看對(duì)象內(nèi)所有屬性與方法,只需要把要查詢的對(duì)象添加到括號(hào)中即可,
比如定義一個(gè)類,然后用dir可以獲取所有的屬性與方法:
???部分輸出結(jié)果:???
7) 查看所有內(nèi)置函數(shù)(BIF)
執(zhí)行:print(dir(sys.modules['builtins'])) 可以打印出所有的內(nèi)置函數(shù)。
8) 多個(gè)語句一行與一個(gè)語句多行
如果你想把多個(gè)語句寫到一行,可以使用; (分號(hào))分隔;
有時(shí)語句可能太長(zhǎng),你可以使用\ (反斜杠)來銜接,
而在[] , {} , ()里的不需要使用反斜杠來銜接。
5.數(shù)據(jù)類型
1) 變量
Python3里定義一個(gè)變量非常簡(jiǎn)單粗暴,直接一個(gè) 變量名 = 初值
賦值時(shí)就決定了變量的數(shù)據(jù)類型,變量名引用了數(shù)值的同時(shí)也引用
它的類型,如果不理解的話,看下例子就知道了,type可以查看
變量的數(shù)據(jù)類型(另外還要注意Python對(duì)大小寫敏感,區(qū)分大小寫!):
???輸出結(jié)果:???
另外Python中支持多個(gè)變量賦值,以下這兩種賦值寫法是正確的:
a = b = c = 1
a,b,c = 1,2,"Python"
對(duì)了,你還可以使用del關(guān)鍵字刪除對(duì)象的引用,但刪除后再調(diào)用
變量是會(huì)報(bào)錯(cuò)的!
???輸出結(jié)果:
2) 數(shù)字(Mumber)
Python3中支持四種數(shù)字類型:int,float,complex(復(fù)數(shù))
注:Python3中 int 不區(qū)分整形與長(zhǎng)整形,整數(shù)的長(zhǎng)度不受限制,
所以很容易進(jìn)行大數(shù)計(jì)算。而除了十進(jìn)制外的進(jìn)制表示如下:
二進(jìn)制0b,八進(jìn)制0o,十六進(jìn)制0x 開頭。
Python支持復(fù)數(shù)直接表示法,就是(a+bj)的形式,complex類的實(shí)例,
可以直接運(yùn)算,比如:*a = 1 + 2j + 3 4j,輸出a,結(jié)果是:(1+14j)實(shí)數(shù)+虛數(shù),除了a+bj,還可以用complex(a,b)表示,兩個(gè)都是
浮點(diǎn)型,可以調(diào)用.real獲得實(shí)部,.imag獲得虛部,abs()求復(fù)數(shù)
的模(√(a^2 + b^2)**)。
數(shù)字類型轉(zhuǎn)換:(Python文檔中,方括號(hào)[]括起來表示為可選)
函數(shù)
作用
int(x[,base])
將x轉(zhuǎn)換為一個(gè)整數(shù),第二個(gè)參數(shù)是指定前面字符串的進(jìn)制類型
float(x)
將x轉(zhuǎn)換到一個(gè)浮點(diǎn)數(shù)
complex(real [,imag])
創(chuàng)建一個(gè)復(fù)數(shù)
str(x)
將對(duì)象x轉(zhuǎn)換為字符串
repr(x)
將對(duì)象x轉(zhuǎn)換為表達(dá)式字符串
eval(str)
用來計(jì)算在字符串中的有效Python表達(dá)式,并返回一個(gè)對(duì)象
tuple(s)
將序列s轉(zhuǎn)換為一個(gè)元組
list(s)
將序列s轉(zhuǎn)換為一個(gè)列表
chr(x)
將一個(gè)整數(shù)轉(zhuǎn)換為一個(gè)字符
unichr(x)
將一個(gè)整數(shù)轉(zhuǎn)換為Unicode字符
ord(x)
將一個(gè)字符轉(zhuǎn)換為它的整數(shù)值
hex(x)
將一個(gè)整數(shù)轉(zhuǎn)換為一個(gè)十六進(jìn)制字符串
oct(x)
將一個(gè)整數(shù)轉(zhuǎn)換為一個(gè)八進(jìn)制字符串
bin(x)
將一個(gè)整數(shù)轉(zhuǎn)換為一個(gè)二進(jìn)制字符串
數(shù)學(xué)函數(shù):
函數(shù)
作用
abs(x)
返回?cái)?shù)字的絕對(duì)值,如abs(-10) 返回 10
ceil(x)
返回?cái)?shù)字的上入整數(shù),如math.ceil(4.1) 返回 5
cmp(x, y)
如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1
exp(x)
返回e的x次冪(ex),如math.exp(1) 返回2.718281828459045
fabs(x)
返回?cái)?shù)字的絕對(duì)值,如math.fabs(-10) 返回10.0
floor(x)
返回?cái)?shù)字的下舍整數(shù),如math.floor(4.9)返回 4
log(x)
如math.log(math.e)返回1.0,math.log(100,10)返回2.0
log10(x)
返回以10為基數(shù)的x的對(duì)數(shù),如math.log10(100)返回 2.0
max(x1, x2,...)
返回給定參數(shù)的最大值,參數(shù)可以為序列。
min(x1, x2,...)
返回給定參數(shù)的最小值,參數(shù)可以為序列。
modf(x)
返回x的整數(shù)部分與小數(shù)部分,兩部分的數(shù)值符號(hào)與x相同,
整數(shù)部分以浮點(diǎn)型表示。
pow(x, y)
x的y次方
round(x [,n])
返回浮點(diǎn)數(shù)x的四舍五入值,如給出n值,則代表舍入到
小數(shù)點(diǎn)后的位數(shù)。
sqrt(x)
返回?cái)?shù)字x的平方根,數(shù)字可以為負(fù)數(shù),返回類型為實(shí)數(shù),
如math.sqrt(4)返回 2+0j
3) 布爾類型(Bool)
用True和False來表示真假,也可以當(dāng)做整數(shù)來對(duì)待,True為1,
False為0,但是不建議用來參與運(yùn)算!
4) 列表(List)
類似于數(shù)組,有序,內(nèi)容長(zhǎng)度可變,使用中括號(hào)[]表示,元素間用逗號(hào)分隔,
元素的數(shù)據(jù)類型可以不一樣!用法示例如下(dir(list)可以查看所有的屬性與方法j):
(Tip:列表可嵌套,如果想訪問列表中的列表中的某個(gè)值可以寫多個(gè)[],比如:list1[1][2])
list1 = [1,2.0,"a",True] # 定義列表
print(list1[1]) # 通過[下標(biāo)]訪問元素,從0開始,結(jié)果輸出:2.0
print(list1[1:3]) # 支持截取,比如這里的[1:3],結(jié)果輸出:[2.0, 'a']
print(list1[1:3:2]) # 還可以有第三個(gè)參數(shù),步長(zhǎng),默認(rèn)為1,結(jié)果輸出:[2.0]
print(list1[2:]) # 輸出結(jié)果:['a', True]
print(list1[-2]) # 負(fù)數(shù)的話從后面開始訪問,結(jié)果輸出:a
print(list1.index("a")) # 返回參數(shù)在列表中的位置,結(jié)果輸出:2
# 修改列表元素
list1[1] = 3.0 # 直接獲得元素后進(jìn)行修改,此時(shí)列表元素:[1, 3.0, 'a', True]
# 添加元素
list1.append('Jay') # 追加一個(gè)元素,此時(shí)列表元素:[1, 2.0, 'a', True, 'Jay']
list1.insert(2,'pig') # 插入一個(gè)元素,此時(shí)列表元素:[1, 2.0, 'pig', 'a', True]
print(list1.pop()) # 移除最后一個(gè)元素,并返回元素的值,結(jié)果輸出:True
# 刪除元素
del list1[0] # 刪除索引位置的值,此時(shí)列表元素:[2.0, 'a', True]
list1.remove('a') # 刪除指定的元素值,此時(shí)列表元素:[1, 2.0, True]
# 其他(使用+號(hào)可以組合列表,*號(hào)可以重復(fù)列表)
print(list1+list1) # 輸出結(jié)果:[1, 2.0, 'a', True, 1, 2.0, 'a', True]
print(list1*2) # 輸出結(jié)果:[1, 2.0, 'a', True, 1, 2.0, 'a', True]
print('a' in list1) # 判斷列表中是否有此元素,輸出結(jié)果:True
print('b' not in list1) # 判斷原始中是不是沒有這個(gè)元素,輸出結(jié)果:True
for x in list: # 迭代遍歷列表
print(len(list1)) # 獲得列表長(zhǎng)度,結(jié)果輸出:4
print(list1.count(1)) # 統(tǒng)計(jì)某個(gè)元素在列表中出現(xiàn)的次數(shù),結(jié)果輸出:2,因?yàn)門rue的值也是1
max(list1) # 獲得列表中的元素最大值,列表元素類型需要為數(shù)字
min(list1) # 獲得列表中的元素最小值,列表元素類型需要為數(shù)字
list1.sort() # 對(duì)原列表元素進(jìn)行排序,本地排序(會(huì)修改值),返回None,
# 只能比較數(shù)字!默認(rèn)從小到大,從大到小可以用可選參數(shù),括號(hào)里加上:
# key = lambda x:-1*x
list1.reverse() # 反轉(zhuǎn)列表元素,會(huì)修改列表,返回None
list2 = list1.copy() # 拷貝列表,重新開辟了內(nèi)存空間!和等號(hào)賦值不一樣!
list(tuple) # 將元組或字符串轉(zhuǎn)換為列表
5) 元組(tuple)
受限的列表,元組中的元素不能修改,使用小括號(hào)()表示。
有一點(diǎn)要注意的是:當(dāng)元組中只有一個(gè)元素,需要在元素后添加逗號(hào),
否則會(huì)當(dāng)做括號(hào)運(yùn)算符使用!元組可以當(dāng)做不能修改的參數(shù)傳遞給函數(shù),
而且元組所占用的內(nèi)存較小。使用的話,除了沒有修改元組元素的方法外,
其他的和列表的方法基本一致。
另外元組中的元素不能刪除,但是可以使用del語句來刪除整個(gè)元組,
不過比較少用,因?yàn)镻ython回收機(jī)制會(huì)在這個(gè)元組不再被使用時(shí)自動(dòng)刪除
(和Java的gc有點(diǎn)像~) 還可以使用tuple(list)將字符串或列表轉(zhuǎn)換為元組。
??輸出結(jié)果:??
6) 字典(dict)
和列表,元組通過下標(biāo)序列來索引元素不同,字典使用鍵值對(duì)的形式來存儲(chǔ)
數(shù)據(jù),通過鍵來索引值,創(chuàng)建字典時(shí),鍵不能重復(fù),重復(fù)后面的會(huì)覆蓋!
因?yàn)殒I必須不可變,所以鍵可用數(shù)字,字符串或元組,但是不能用列表!
使用冒號(hào):分割鍵與值,多個(gè)鍵值對(duì)用逗號(hào),分隔;字典也是支持嵌套的!
用法示例如下:
dict1 = {} # 定義一個(gè)空字典
dict2 = {'a': 1, 'b': 2, 3: "c"} # 定義一個(gè)普通字典
dict4 = dict2.copy() # 淺復(fù)制一個(gè)字典
# 可以使用fromkeys創(chuàng)建并返回新的字典,有兩個(gè)參數(shù),鍵和鍵對(duì)應(yīng)的值
# 值可以不提供,默認(rèn)None,不過有個(gè)小細(xì)節(jié)要注意,下面的例子輸出
# 的結(jié)果是:{1: ['a', 'b', 'c'], 2: ['a', 'b', 'c'], 3: ['a', 'b', 'c']}
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
dict3 = {}
dict3 = dict3.fromkeys(list1, list2)
print(dict3)
# 通過鍵查詢對(duì)應(yīng)的值,如果沒有這個(gè)鍵會(huì)報(bào)錯(cuò)TypeError,這里輸出結(jié)果:2
print(dict2['b'])
print(dict2.get("d")) # 通過get()方法查詢鍵對(duì)應(yīng)的值,沒有的話會(huì)返回None
# 還可以加上一個(gè)默認(rèn)的返回參數(shù)get(x,y)
print(dict2.setdefault("d")) # 和get()類似,如果找不到鍵的話會(huì)自動(dòng)添加 鍵:None
print("d" in dict2) # 字典中是否有此鍵,這里輸出結(jié)果:False
print("d" not in dict2) # 字典中是否沒有此鍵,這里輸出結(jié)果:True
print(dict2.keys()) # 返回字典中所有的鍵,這里輸出結(jié)果:dict_keys(['a', 3, 'b'])
print(dict2.values()) # 返回字典中所有的值,這里輸出結(jié)果:dict_values([1, 'c', 2])
print(dict2.items()) # 返回字典中所有的鍵值對(duì),這里輸出結(jié)果:
# dict_items([('a', 1), (3, 'c'), ('b', 2)])
# 修改鍵對(duì)應(yīng)的值,此時(shí)字典元素:{3: 'c', 'a': 1, 'b': 'HaHa'}
dict2['b'] = 'HaHa'
dict2.update(b:'Pig') # 使用update方法可以更新鍵對(duì)應(yīng)的值,不過鍵需要為字符串!
# 刪除字典元素
del(dict2['b']) # 刪除某個(gè)鍵值對(duì),此時(shí)字典元素:{3: 'c', 'a': 1}
dict2.clear() # 移除字典中所有的鍵值對(duì),此時(shí)剩下空字典:{}
del dict2 # 刪除整個(gè)字典,刪除后無法再重復(fù)引用!!!
print(dict2.pop('a')) # 根據(jù)鍵刪除對(duì)應(yīng)的值,返回被刪除的值。
print(dict2.popitem()) # 刪除一個(gè)項(xiàng),隨機(jī),比如:('b', 2)
# 遍歷字典:
for d in dict2:
print("%s:%s" % (d, dict2.get(d)))
for (k,v) in dict2.items():
print("%s:%s" % (k, v))
7) 集合(set)
集合中的存儲(chǔ)的元素?zé)o序且不重復(fù),所以你無法去索引某個(gè)具體的元素;
使用大括號(hào){}包裹元素,逗號(hào)分隔,如果有重復(fù)的元素會(huì)被自動(dòng)剔除!
另外有一點(diǎn)要注意的是,如果是創(chuàng)建空集合必須使用set(),而不能用{},
通過上面我們也知道了{(lán)}的話是直接創(chuàng)建一個(gè)空字典!
用法示例如下:
set1 = set() # 創(chuàng)建空集合
set2 = {1, 2, 3, 4, 5, 1} # 普通方式創(chuàng)建集合
print(set2) # 重復(fù)元素會(huì)被自動(dòng)刪除,輸出結(jié)果:{1, 2, 3, 4, 5}
set3 = set('12345') # 字符串
print(set3) # 輸出:{'2', '5', '3', '4', '1'},集合元素?zé)o序
print(6 in set2) # 判斷集合中是否有此元素:輸出結(jié)果:False
print(6 not in set2) # 判斷集合中是否有此元素:輸出結(jié)果:True
set2.add("6") # 添加元素
print(set2) # 輸出結(jié)果:{1, 2, 3, 4, 5, '6'}
set2.remove(2) # 刪除元素,如果刪除的元素不存在會(huì)報(bào)錯(cuò)
print(set2) # 輸出結(jié)果:{1, 3, 4, 5, '6'}
# 遍歷集合,輸出結(jié)果: 1 3 4 5 6
for data in set2:
print(data, end="\t")
# 使用frozenset()函數(shù)定義不可變集合
set4 = frozenset({1, 2, 3, 4, 5})
8) 字符串
Python里對(duì)處理字符串可是日常,熟練掌握字符串的處理非常重要。
可以使用單引號(hào)('')或者雙引號(hào)("")來修飾字符串,
如果想讓字符串包含換行縮進(jìn)等格式時(shí),可以使用三括號(hào)('''''')
來修飾,一般要打印段落文字的時(shí)候可以用這個(gè)。
另外,字符串定義后就不能修改元素了,比如下面str1[0] = 'x'是會(huì)報(bào)錯(cuò)的,
只能通過+,*,分片等方式進(jìn)行拼接,間接得到相同的字符串內(nèi)容,不過卻不是原來
的字符了,變量指向了新的字符串,而舊的會(huì)被py的回收機(jī)制回收掉!
訪問字符串:
str1 = "Hello Python"
print(str1[3]) # 輸出結(jié)果:l
print(str1[2:]) # 輸出結(jié)果:llo Python
print(str1[2:5]) # 輸出結(jié)果:llo
print(str1[2:10:2]) # 輸出結(jié)果:loPt
print(str1[0:8] + str1[8:]) # 輸出結(jié)果:Hello Python
str2 = str1[6:] * 3
print(str2) # 輸出結(jié)果:PythonPythonPython
轉(zhuǎn)義字符:
轉(zhuǎn)義字符
作用
轉(zhuǎn)義字符
作用
轉(zhuǎn)義字符
作用
行尾的\
續(xù)行符
\\
反斜杠
\'
單引號(hào)
\a
響鈴
\b
退格
\e
轉(zhuǎn)義
\000
空
\n
換行
\v
縱向制表符
\t
橫向制表符
\r
回車
\f
換頁
\o
八進(jìn)制數(shù)代表字符
\x
十六進(jìn)制數(shù)代表字符
各種內(nèi)置方法:
方法名
作用
capitalize()
把字符串的第一個(gè)字符改為大寫
casefold()
把整個(gè)字符串的所有字符改為小寫
center(width)
將字符串居中,并使用空格填充至長(zhǎng)度width的新字符串
count(sub[,start[,end]])
返同sub在字符申里邊出現(xiàn)的次數(shù),
start和end參數(shù)表示范圍,可選
encode(encoding= 'utf-8 ',errors='strict')
以encoding指定的編碼格式對(duì)字符串進(jìn)行編碼
endswith(sub[,start[,end]])
檢查字符串是否以sub 子字符串結(jié)束,如果是返回True,
否則返回False。start和end參數(shù)表示范圍,可選
expandtabs([tabsize= 8])
把字符串中的tab符號(hào)(\t)轉(zhuǎn)換為空格,如不指定參數(shù),
默認(rèn)的空格數(shù)是tabsize=8
find(sub[,start[,end]])
檢測(cè)sub是否包含在字符串中,如果有則返回索引值,
否則返回-1,start和end參數(shù)表示范圍,可選
index(sub[,start[,end]])
跟find方法一樣,不過如果sub不在string中會(huì)產(chǎn)生一個(gè)異常
isalnum()
如果字符串中至少有一個(gè)字符,并且所有字符都是
字母或數(shù)字則返回True,否則返回False
isalpha()
如果字符串至少有一個(gè)字符串,并且所有字符都是
字母則返回True,否則返回False
isdecimal()
如果字符串只包含十進(jìn)制數(shù)字則返回True,否則返回False
isdigit()
如果字符串只包含數(shù)字則返回True,否則返回False
islower()
如果字符串中至少包含一個(gè)區(qū)分大小寫的字符,并且這些字符
都是小寫,則返回True,否則返回False
isnumeric()
如果字符串中只包含數(shù)字字符,則返回True,否則返回False
isspace()
如果字符串中只包含空格,則返回True,否則返回False
istitle()
如果字符串是標(biāo)題化(所有單詞大寫開頭,其余小寫),
則返回True,否則返回False
isupper()
如果字符串中至少包含一個(gè)區(qū)分大小寫的字符,并且這些
字符都是大寫,則返回True,否則返回False
join(sub)
以字符串作為分隔符,插入到sub中所有的字符之間,使用+去拼接大量
字符串的時(shí)候是很低效率的,因?yàn)榧犹?hào)拼接會(huì)引起內(nèi)存賦值一級(jí)垃圾回收
操作,此時(shí)用join來拼接效率會(huì)高一些,比如: ''.join(['Hello','Python'])
ljust(width)
返回一個(gè)左對(duì)齊的字符串,并使用空格填充至長(zhǎng)度為width的新字符串
lower()
轉(zhuǎn)換字符串所有大寫字符為小寫
lstrip()
去除字符串左邊的所有空格
partition(sub)
找到子字符串sub,把字符串分割成3元組(前,pre,后)
如果字符串中不包含則返回('原字符串','','')
replace(old, new[,count])
把字符串中的old子字符串替換成new,如果count指定,
則替換次數(shù)不超過count次
rfind(sub[,start[,end]])
和find()方法類似,不過是從右開始查找
rindex(sub[,start[,end]])
和index()方法類似,不過是從右開始查找
rjust(width)
返回一個(gè)右對(duì)齊的字符串,并使用空格填充至長(zhǎng)度為width的新字符串
rpartition(sub)
類似于partition(),不過是從右邊開始查找
rstrip()
刪除字符串末尾的空格
split(sep=None,maxsplit=-1)
不帶參數(shù)默認(rèn)是以空格為分隔符切片字符串,如果maxspli參數(shù)t
右設(shè)置,則僅分隔maxsplit個(gè)子字符串,返回切片后的子字符串拼接的列表
splitlines([keepends])
按照'\n'分隔,返回一個(gè)包含各行作為元素的列表,如果keepends參數(shù)
指定,則返回前keepends行
startswith(prefix[,start[,end]])
檢查字符串是否以prefix開頭,是則返回True,否則返回False。
start和end參數(shù)可以指定范圍檢查,可選
strip([chars])
刪除字符串前邊和后邊所有的空格,chars參數(shù)可定制刪除的字符串,可選
swapcase()
反轉(zhuǎn)字符串中的大小寫
title()
返回標(biāo)題化(所有的單詞都是以大寫開始,其余字母小寫)的字符串
translate(table)
按照table的規(guī)則(可由str.maketrans('a','b')定制)轉(zhuǎn)換字符串中的字符
upper()
轉(zhuǎn)換字符串中所有的小寫字符為大寫
zfill(width)
返回長(zhǎng)度為width的字符串,原字符串右對(duì)齊,前邊用0填充
字符串格式化:
其實(shí)就是format方法的使用而已,示例如下:
# 位置參數(shù)
str1 = "{0}生{1},{2}{3}!".format("人","苦短","我用","Python")
print(str1) # 輸出結(jié)果:人生苦短,我用Python!
# 關(guān)鍵字參數(shù)
str1 = "{a}生{c},{b}ze8trgl8bvbq!".format(a = "人", c = "苦短",b = "我用",d = "Python")
print(str1) # 輸出結(jié)果:人生苦短,我用Python!
# 位置參數(shù)可以與關(guān)鍵字參數(shù)一起使用,不過位置參數(shù)需要在關(guān)鍵字參數(shù)前,否則會(huì)報(bào)錯(cuò)!
# 另外還有個(gè)叫替換域的東西,冒號(hào)代表格式化符號(hào)開始,比如下面的例子:
str1 = "{0}:{1:.4}".format("圓周率", 3.1415926)
print(str1) # 輸出結(jié)果:圓周率:3.142
格式化操作符:%,這個(gè)就不說了,和上面print()那里的一致!
9) 運(yùn)算符
算術(shù)操作符:(+ - * / % **(冪,次方) //(地板除法,舍棄小數(shù)))
print("3 + 7 = %d" % (3 + 7)) # 輸出結(jié)果: 3 + 7 = 10
print("3 - 7 = %d" % (3 - 7)) # 輸出結(jié)果: 3 - 7 = -4
print("3 * 7 = %d" % (3 * 7)) # 輸出結(jié)果: 3 * 7 = 21
print("7 / 3 = %f" % (7 / 3)) # 輸出結(jié)果: 7 / 3 = 2.333333
print("7 %% 3 = %d" % (7 % 3)) # 輸出結(jié)果: 7 % 3 = 1
print("3 ** 6 = %d" % (7 ** 3)) # 輸出結(jié)果: 3 ** 6 = 343
print("3 // 6 = %f" % (7 // 3)) # 輸出結(jié)果: 3 // 6 = 2.000000
比較運(yùn)算符:(== != > < >= <=)
賦值運(yùn)算符:(== += -= *`=** **/=** **%=** **=` //=)
位運(yùn)算符:(&(按位與) |(按位或) ^(異或,不同為1) ~(取反) << >>)
邏輯運(yùn)算符:(and or not)
成員運(yùn)算符:(in not in)
身份運(yùn)算符(判斷是否引用同一個(gè)對(duì)象):(is is not)
運(yùn)算符優(yōu)先級(jí):
**(指數(shù)) ??>?? ~ + -(取反,正負(fù)號(hào)) ??>?? * / % //(乘除,求余,地板除) ??>?? << >>(左右移)
> ?? &(按位與) ??>??^ |(異或,按位或)??> ??< <= > >=(比較運(yùn)算符) ??>??等于運(yùn)算符??> ??賦值運(yùn)算符
>??身份運(yùn)算符??>??成員運(yùn)算符??>??邏輯運(yùn)算符
10) 日期時(shí)間
日期時(shí)間并不屬于數(shù)據(jù)結(jié)構(gòu),只是覺得很常用,索性也在這里把用法mark下~
以來的兩個(gè)模塊是:time 和 datetime,詳細(xì)用法示例如下:
import time, datetime
# 獲取當(dāng)前時(shí)間
moment = time.localtime()
print("年:%s" % moment[0])
print("月:%s" % moment[1])
print("日:%s" % moment[2])
print("時(shí):%s" % moment[3])
print("分:%s" % moment[4])
print("秒:%s" % (moment[5] + 1))
print("周幾:%s" % (moment[6] + 1))
print("一年第幾天:%s" % moment[7])
print("是否為夏令時(shí):%s" % moment[8])
# 格式化時(shí)間(這里要注意strftime和strptime是不一樣的!!!)
moment1 = time.strftime('%Y-%m-%d %H:%M:%S')
moment2 = time.strftime('%a %b %d %H:%M:%S %Y', time.localtime())
moment3 = time.mktime(time.strptime(moment2, '%a %b %d %H:%M:%S %Y'))
print(moment1) # 輸出結(jié)果:2017-12-02 11:08:02
print(moment2) # 輸出結(jié)果:Sat Dec 02 11:08:02 2017
print(moment3) # 輸出結(jié)果:1512184082.0 日期轉(zhuǎn)換為時(shí)間戳
# 獲得當(dāng)前時(shí)間戳
print(time.time()) # 輸出結(jié)果:1512185208.0942981
# 獲得當(dāng)前時(shí)間(時(shí)間數(shù)組,還需strftime格式化下)
print(datetime.datetime.now()) # 輸出結(jié)果:2017-12-02 11:34:44.726843
# 時(shí)間戳轉(zhuǎn)換為時(shí)間
# 方法一:(輸出結(jié)果:2017-12-02 11:08:02)
moment4 = 1512184082
moment5 = time.localtime(moment4) # 轉(zhuǎn)換成時(shí)間數(shù)組
print(time.strftime('%Y-%m-%d %H:%M:%S', moment5)) # 格式化
# 方法二:
moment6 = datetime.datetime.utcfromtimestamp(moment4)
print(moment6) # 直接輸出:2017-12-02 03:08:02
moment7 = moment6.strftime('%a %b %d %H:%M:%S %Y')
print(moment7) # 格式化后輸出:Sat Dec 02 03:08:02 2017
# 延遲執(zhí)行
time.sleep(秒)
6.流程控制
1) if條件判斷
python中沒有switch-case,另外使用了 elif 代替了else if
每個(gè)條件后需要跟一個(gè)冒號(hào)(:),通過縮放來劃分代碼塊,
嵌套的時(shí)候要注意!使用示例如下:
???輸出結(jié)果:
另外,如果條件成立,你又不想做任何事情,可以直接使用pass空語句
2) while循環(huán)
python中沒有do-while,同樣要注意冒號(hào)和縮放!
可以搭配else使用,還有無限循環(huán)這種東西:while True:
使用下面的break關(guān)鍵字可以跳出循環(huán)。
使用示例如下:
???輸出結(jié)果:
3) for循環(huán)
和C或者Java那種for循環(huán)不同,并不能直接寫 for(int a = 0;a < 100;a++)
使用示例如下:
輸出結(jié)果:
4) break,continue,else
break跳出循環(huán);continue跳過余下操作直接進(jìn)入下一次循環(huán);
else也可以使用在循環(huán),for循環(huán)條件不成立時(shí)執(zhí)行,如果先break的話不會(huì)執(zhí)行!
5) 條件表達(dá)式(簡(jiǎn)化版的if-else)
a = x if 條件 else y
6) 斷言
當(dāng)assert關(guān)鍵字后面的判斷條件為假的時(shí)候,程序自動(dòng)崩潰并拋出AssertionErro異常,
一般在測(cè)試程序的時(shí)候才會(huì)用到,要確保某個(gè)條件為真程序才能正常工作的時(shí)候使用~
7) 迭代器與生成器
迭代器:用于訪問集合,是一種可以記住遍歷位置的對(duì)象,會(huì)從第一個(gè)元素
開始訪問,直到結(jié)束,兩個(gè)基本的方法:iter()和next()
輸出結(jié)果:
生成器
應(yīng)該叫生成器函數(shù)吧,一種特別的函數(shù),用yield來返回值,
調(diào)用時(shí)會(huì)返回一個(gè)生成器對(duì)象,本質(zhì)上還是迭代器,只是更加簡(jiǎn)潔,
yield對(duì)應(yīng)的值在函數(shù)調(diào)用的時(shí)候不會(huì)立即返回,只有去調(diào)用next()
方法的時(shí)候才會(huì)返回,使用for x in xxx的時(shí)候其實(shí)調(diào)用的還是next()方法,
最簡(jiǎn)單的使用示例如下:
???輸出結(jié)果:???
如果你用type()方法查下,會(huì)發(fā)現(xiàn)返回的對(duì)象類型是:``
相比起迭代器,生成器更加簡(jiǎn)潔優(yōu)雅,最經(jīng)典的例子就是實(shí)現(xiàn)斐波那契數(shù)列:
def func(n):
a, b = 0, 1
while n > 0:
n -= 1
yield b
a, b = b, a + b
for i in func(10):
print(i, end="\t")
# 輸出結(jié)果:1 1 2 3 5 8 13 21 34 55
7.函數(shù)
對(duì)于一些重復(fù)使用的代碼塊,我們可以把他抽取出來寫成一個(gè)函數(shù)。
1) 函數(shù)定義
使用 def關(guān)鍵字 修飾,后接函數(shù)名與圓括號(hào)(傳入?yún)?shù)),
使用 return關(guān)鍵字 返回值,不寫的話默認(rèn)返回 None值,
Python可以動(dòng)態(tài)確定函數(shù)類型,返回不同的類型的值,可以利用
列表打包多種類型的值一次性返回,也可以直接用元組返回多個(gè)值;
另外函數(shù)參數(shù)如果有多個(gè)的話,可以用逗號(hào)隔開。
還有一個(gè)建議是:在函數(shù)第一行語句可以選擇性地使用文檔字符串用于存放
函數(shù)說明,直接用三引號(hào)注釋包括即可,通過help方法可以拿到!
2) 形參與實(shí)參
定義函數(shù)時(shí)的參數(shù)是形參,調(diào)用時(shí)傳入的是實(shí)參;
3) 關(guān)鍵字參數(shù)
參數(shù)有多個(gè)的時(shí)候,怕參數(shù)混淆傳錯(cuò),可以在傳入的時(shí)候
指定形參的參數(shù)名,比如: show(a = "a", b = "b")這樣。
4) 默認(rèn)參數(shù)
定義的形參時(shí)候賦予默認(rèn)初值,調(diào)用時(shí)就可以不帶
參數(shù)去調(diào)用函數(shù),比如:def sub(a = "1", b = "2"),調(diào)用時(shí)直接
什么都傳sub()或者傳入一個(gè)參數(shù)sub(3)都可以,還可以配合
關(guān)鍵字參數(shù)指定傳入的是哪個(gè)參數(shù)。
5) 可變參數(shù)
有時(shí)傳入的函數(shù)參數(shù)數(shù)目可能是不固定的,比如,要你
計(jì)算一組值的和,具體有多少個(gè)數(shù)字不知道,此時(shí)就可以用可變參數(shù)了。
只需要在參數(shù)前加上*號(hào)(其實(shí)是把數(shù)據(jù)打包成了元組),就代表這個(gè)
參數(shù)是可變參數(shù);如果有多個(gè)參數(shù),寫在可變參數(shù)后的參數(shù)要用
關(guān)鍵字參數(shù)指定,否則會(huì)加入可變參數(shù)的范疇!!!有打包自然有解包,如果想把列表或元組當(dāng)做可變參數(shù)傳入,需要在傳入的時(shí)候
在實(shí)參前加上*號(hào)!另外,如果想把參數(shù)打包成元組的方式的話,
可以使用兩個(gè)星號(hào)(``**)修飾~
6) 全局變量與局部變量
全局變量就是定義為在最外部的,可以在函數(shù)內(nèi)部進(jìn)行訪問但不能直接修改;
局部變量就是定義在函數(shù)內(nèi)部的,而在函數(shù)外部無法訪問的參數(shù)或變量;
局部變量無法在外部訪問的原因:
Python在運(yùn)行函數(shù)時(shí),會(huì)利用棧(Stack)來存儲(chǔ)數(shù)據(jù),執(zhí)行完
函數(shù)后,所有數(shù)據(jù)會(huì)被自動(dòng)刪除。
函數(shù)中無法修改全局變量的原因:
當(dāng)試圖在函數(shù)里修改全局變量的值時(shí),Python會(huì)自動(dòng)在函數(shù)內(nèi)部新建一個(gè)
名字一樣的局部變量代替。如果硬是要修改,可以在函數(shù)內(nèi)部使用
global關(guān)鍵字 修飾全局變量,但是不建議這樣做,會(huì)使得程序
維護(hù)成本的提高。
7) 內(nèi)部函數(shù)
其實(shí)就是函數(shù)嵌套,一個(gè)函數(shù)里嵌套另一個(gè)函數(shù),需要注意一點(diǎn):
內(nèi)部函數(shù)的作用域只在內(nèi)部函數(shù)的直接外部函數(shù)內(nèi),外部是
無法調(diào)用的,如果調(diào)用會(huì)報(bào)錯(cuò)的。
8) 閉包
Python中的閉包:如果在一個(gè)外部函數(shù)中,對(duì)外部作用域(非全局)的變量
進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包。簡(jiǎn)單的例子如下:
??? 輸出結(jié)果:???
不能在外部函數(shù)以外的地方調(diào)用內(nèi)部函數(shù),會(huì)報(bào)方法名未定義。
另外,內(nèi)部函數(shù)也不能直接修改外部函數(shù)里的變量,會(huì)報(bào)UnboundLocalError錯(cuò)誤!
和前面函數(shù)里修改全局變量的情況一樣,如果硬是要修改的話
可以把外部函數(shù)中的變量間接通過容器類型來存放,或者使用
Python3 中提供的nolocal關(guān)鍵字修飾修改的變量。例子如下:
??? 輸出結(jié)果:??? 400
9) lambda表達(dá)式
在Python中可以使用lambda關(guān)鍵字來創(chuàng)建匿名函數(shù),直接返回一個(gè)函數(shù)對(duì)象,
不用去糾結(jié)起什么名字,省了定義函數(shù)的步驟,從而簡(jiǎn)化代碼的可讀性!
簡(jiǎn)單的對(duì)比大小lambda表達(dá)式例子如下:
big = lambda x, y: x > y
print("第一個(gè)參數(shù)比第二個(gè)參數(shù)大:%s" % big(1, 2))
# 輸出結(jié)果:第一個(gè)參數(shù)比第二個(gè)參數(shù)大:False
10) 遞歸
其實(shí)就是函數(shù)調(diào)用自身,最簡(jiǎn)單的遞歸求和例子如下:
def sum(n):
if n == 1:
return 1
else:
return n + sum(n - 1)
print("1到100的求和結(jié)果是: %d" % sum(100))
# 輸出結(jié)果:1到100的求和結(jié)果是: 5050
8.異常處理
1) 語法錯(cuò)誤與運(yùn)行異常區(qū)分
語法錯(cuò)誤是連編譯器那關(guān)都過不了的錯(cuò)誤,比如if后漏掉:冒號(hào),跑都跑不起來;
運(yùn)行異常則是程序跑起來后,因?yàn)槌绦虻臉I(yè)務(wù)邏輯問題引起的程序崩潰,比如除以0;
2) Python中的常見異常
異常
描述信息
AssertionError
斷言語句失敗
AttributeError
嘗試訪問未知的對(duì)象屬性
IndexError
索引超出序列的范圍
keyError
字典中查找一個(gè)不存在的Key
NameError
嘗試訪問一個(gè)不存在的變量
OSError
操作系統(tǒng)產(chǎn)生的異常,比如FileNotFoundError
SyntaxError
Python語法錯(cuò)誤
TypeError
不同類型間的無效操作
ZeroDivisionError
除數(shù)為0
IOError
輸入輸出錯(cuò)誤
ValueError
函數(shù)傳參類型錯(cuò)誤
3) 異常捕獲
try-expect-else語句,try-finally語句
# 1.最簡(jiǎn)單的,try捕獲了任何異常,直接丟給except后的代碼塊處理:
try:
result = 1 / 0
except:
print("捕獲到異常了!") # 輸出:捕獲到異常了!
# 2.捕獲特定類型:
try:
result = 1 / 0
except ZeroDivisionError:
print("捕獲到除數(shù)為零的錯(cuò)誤") # 輸出:捕獲到除數(shù)為零的錯(cuò)誤
# 3.針對(duì)不同的異常設(shè)置多個(gè)except
try:
sum = 1 + '2'
result = 1 / 0
except TypeError as reason:
print("類型出錯(cuò):" + str(reason))
except ZeroDivisionError as reason:
print("除數(shù)為0:" + str(reason))
# 輸出:類型出錯(cuò):unsupported operand type(s) for +: 'int' and 'str'
# 4.對(duì)多個(gè)異常統(tǒng)一處理
try:
result = 1 / 0
sum = 1 + '2'
except (TypeError, ZeroDivisionError) as reason:
print(str(reason)) # 輸出:division by zero
# 5.當(dāng)沒有檢測(cè)到異常時(shí)才執(zhí)行的代碼塊,可以用else
try:
result = 4 / 2
except ZeroDivisionError as reason:
print(str(reason))
else:
print("沒有發(fā)生異常,輸出結(jié)果:%d" % result)
# 輸出:沒有發(fā)生異常,輸出結(jié)果:2
# 6.無論是否發(fā)生異常都會(huì)執(zhí)行的一段代碼塊,比如io流關(guān)閉,
# 可以使用finally子句,如果發(fā)生異常先走except子句,后走finally子句。
try:
result = 4 / 2
except ZeroDivisionError as reason:
print(str(reason))
else:
print("沒有發(fā)生異常,輸出結(jié)果:%d" % result)
finally:
print("無論是否發(fā)生異常都會(huì)執(zhí)行~")
# 輸出結(jié)果:
# 沒有發(fā)生異常,輸出結(jié)果:2
# 無論是否發(fā)生異常都會(huì)執(zhí)行~
4) 拋出異常
使用raise語句可以直接拋出異常,比如raise TypeError(異常解釋,可選)
5) 上下文管理-with語句
當(dāng)你的異常捕獲代碼僅僅是為了保證共享資源(文件,數(shù)據(jù)等)的唯一分配,
并在任務(wù)結(jié)束后釋放掉它,那么可以使用with語句,例子如下:
try:
with open('123.txt', "w") as f:
for line in f:
print(line)
except OSError as reason:
print("發(fā)生異常:" + str(reason))
# 輸出結(jié)果:發(fā)生異常:not readable
6) sys.exc_info 函數(shù)
除了上面獲取異常信息的方式外,還可以通過sys模塊的exc_info() 函數(shù)獲得:
示例如下:
# 輸出結(jié)果依次是:異常類,類示例,跟蹤記錄對(duì)象
try:
result = 1 / 0
except:
import sys
tuple_exception = sys.exc_info()
for i in tuple_exception:
print(i)
# 輸出結(jié)果:
#
# division by zero
#
9.文件存儲(chǔ)
1) open函數(shù)與文件打開模式
Python中讀寫文件非常簡(jiǎn)單,通過open()函數(shù) 可以打開文件并
返回文件對(duì)象使用help命令可以知道,open函數(shù)有好幾個(gè)參數(shù):
作為初學(xué)者,暫時(shí)了解前兩個(gè)參數(shù)就夠了:
file參數(shù):文件名,不帶路徑的話會(huì)在當(dāng)前文件夾中查找;
mode:打開模式,有以下幾種打開方式:
模式
作用
r
只讀模式打開,默認(rèn)
w
寫模式打開,若文件存在,先刪除,然后重新創(chuàng)建
a
追加模式打開,追加到文件末尾,seek()指向其他地方也沒用,文件不存在,自動(dòng)創(chuàng)建
b
二進(jìn)制模式打開
t
文本模式打開,默認(rèn)
+
可讀寫模式,可配合其他模式使用,比如r+,w+
x
如果文件已存在,用此模式打開會(huì)引發(fā)異常
U
通用換行符支持
2) 文件對(duì)象的方法
函數(shù)
作用
close()
關(guān)閉文件,關(guān)閉后文件不能再進(jìn)行讀寫操作
read(size=-1)
從文件讀取指定的字節(jié)數(shù),如果未設(shè)置或?yàn)樨?fù)數(shù),讀取所有
next()
返回文件下一行
readline()
讀取整行,包括換行符'\n'
seek(offset, from)
設(shè)置當(dāng)前文件指針的位置,從from(0文件起始位置,1當(dāng)前位置,
2文件末尾)偏移offset個(gè)字節(jié)
tell()
返回文件的當(dāng)前位置
write(str)
將字符串寫入文件
writelines(seq)
寫入一個(gè)序列字符串列表,如果要換行,需要自己加入每行的換行符
3) 使用例子
# 讀取123.txt文件里的內(nèi)容打印,同時(shí)寫入到321.txt中
try:
f1 = open("321.txt", "w")
with open("123.txt", "r") as f2:
for line in f2:
print(line, end="")
f1.write(line)
except OSError as reason:
print("發(fā)生異常" + str(reason))
finally:
f1.close() # 用完要關(guān)閉文件,f2不用是因?yàn)橛昧藈ith
輸出結(jié)果:
????
4) OS模塊中關(guān)于文件/目錄的常用函數(shù)
需要導(dǎo)入os模塊,使用的時(shí)候需加上模塊引用,比如os.getcwd()
函數(shù)
作用
getcwd()
返回當(dāng)前工作目錄
chdir(path)
改變當(dāng)前工作目錄
listdir(path='.')
不寫參數(shù)默認(rèn)列舉當(dāng)前目錄下所有文件和文件夾,'.'當(dāng)前目錄,'..'上一層目錄
mkdir(path)
創(chuàng)建文件夾,若存在會(huì)拋出FileExistsError異常
mkdirs(path)
可用于創(chuàng)建多層目錄
remove(path)
刪除指定文件
rmdir(path)
刪除目錄
removedirs(path)
刪除多層目錄
rename(old,new)
重命名文件或文件夾
system(command)
調(diào)用系統(tǒng)提供的小工具,比如計(jì)算器
walk(top)
遍歷top參數(shù)指定路徑下所有子目錄,返回一個(gè)三元組(路徑,[包含目錄],[包含文件])
curdir
當(dāng)前目錄(.)
pardir
上一節(jié)目錄(..)
sep
路徑分隔符,Win下是'\',Linux下是'/'
linesep
當(dāng)前平臺(tái)使用的行終止符,win下是'\r\n',Linux下是'\n'
name
當(dāng)前使用的操作系統(tǒng)
os.path模塊(文件路徑相關(guān))
函數(shù)
作用
dirname(path)
獲得路徑名
basename(path)
獲得文件名
join(path1[,path2[,...]])
將路徑名與文件名拼接成一個(gè)完整路徑
split(path)
分割路徑與文件名,返回元組(f_path, f_name),如果完全使用目錄,
它也會(huì)將最后一個(gè)目錄作為文件名分離,且不會(huì)判斷文件或目錄是否存在
splitext(path)
分隔文件名與擴(kuò)展名
getsize(file)
獲得文件大小,單位是字節(jié)
getatime(file)
獲得文件最近訪問時(shí)間,返回的是浮點(diǎn)型秒數(shù)
getctime(file)
獲得文件的創(chuàng)建時(shí)間,返回的是浮點(diǎn)型秒數(shù)
getmtime(file)
獲得文件的修改時(shí)間,返回的是浮點(diǎn)型秒數(shù)
exists(path)
判斷路徑(文件或目錄)是否存在
isabs(path)
判斷是否為決定路徑
isdir(path)
判斷是否存在且是一個(gè)目錄
isfile(path)
判斷是否存在且是一個(gè)文件
islink(path)
判斷是否存在且是一個(gè)符號(hào)鏈接
ismount(path)
判斷是否存在且是一個(gè)掛載點(diǎn)
samefile(path1,path2)
判斷兩個(gè)路徑是否指向同一個(gè)文件
wenji
10.類與對(duì)象
1) 最簡(jiǎn)單的例子
PS:Python中沒有像其他語言一樣有public或者private的關(guān)鍵字
來區(qū)分公有還是私有,默認(rèn)公有,如果你想定義私有屬性或者函數(shù),
命名的時(shí)候在前面加上兩下劃線__即可,其實(shí)是偽私有,內(nèi)部
采用的是名字改編技術(shù),改成了_類名__私有屬性/方法名,比如
下面調(diào)用people._Person__skill,是可以訪問到私有成員的!
類中的屬性是靜態(tài)變量。
輸出結(jié)果:
2) __init__(self) 構(gòu)造方法
實(shí)例化對(duì)象的時(shí)候會(huì)自動(dòng)調(diào)用,當(dāng)你想傳參的時(shí)候可以用它~
輸出結(jié)果:
3) 繼承
規(guī)則如下:
1.繼承寫法: class 子類(父類):
2.子類可以繼承父類的所有屬性與方法;
3.子類定義與父類同名的屬性與方法會(huì)自動(dòng)覆蓋;
4.重寫時(shí)如果想調(diào)用父類的同名方法可以使用super()函數(shù). 方法名調(diào)用;
Python支持多繼承,多個(gè)父類用逗號(hào)隔開,子類可同時(shí)繼承多個(gè)父類的
屬性與方法多繼承的時(shí)候如果父類們中有相同的方法,調(diào)用的順序是
誰在前面先調(diào)用那個(gè)父類中的方法,比如有class Person(Name, Sex,Age),
三個(gè)父類里都有一個(gè)show的方法,那么子類調(diào)用的是Name里的show()!
如果不是得用多繼承不可的話,應(yīng)該盡量避免使用它,有時(shí)會(huì)出現(xiàn)
一些不可遇見的BUG。
還有一種叫組合的套路,就是在把需要用到的類丟到組合類中
實(shí)例化,然后使用,比如把Book,Phone,Wallet放到Bag里:
輸出結(jié)果:
4) 與對(duì)象相關(guān)的一些內(nèi)置函數(shù)
函數(shù)
作用
issubclass(class, classinfo)
如果第一個(gè)參數(shù)是第二個(gè)參數(shù)的子類,返回True,否則返回False
isinstance(object, classinfo)
如果第一個(gè)參數(shù)是第二個(gè)參數(shù)的實(shí)例對(duì)象,返回True,否則返回False
hasattr(object, name)
測(cè)試一個(gè)對(duì)象中是否有指定的屬性,屬性名要用引號(hào)括著!
getattr(object, name, [,default])
返回對(duì)象的指定屬性值,不存在返回default值,沒設(shè)會(huì)報(bào)ArttributeError異常
setattr(object, name, value)
設(shè)置對(duì)象中指定屬性的值,屬性不存在會(huì)新建并賦值
delattr(object, name)
刪除對(duì)象中的指定屬性的值,不存在會(huì)報(bào)報(bào)ArttributeError異常
property(fget,fset,fdel,doc)
返回一個(gè)可以設(shè)置屬性的屬性
11.模塊
1) 導(dǎo)入模塊
保存為.py后綴的文件都是一個(gè)獨(dú)立的模塊,比如有a.py和b.py文件,
你可以在a中import b,然后就可以使用b.py中的函數(shù)了。
模塊導(dǎo)入規(guī)則4.1 導(dǎo)包處就寫得詳細(xì)了,此處就不重復(fù)描述了。
2) 指定模塊
導(dǎo)入其他模塊的時(shí)候,測(cè)試部分的代碼也會(huì)執(zhí)行,可以通過
__name__告訴Python該模塊是作為程序運(yùn)行還是導(dǎo)入到其他程序中。
作為程序運(yùn)行時(shí)該屬性的值是__main__,只有單獨(dú)運(yùn)行的時(shí)候才會(huì)執(zhí)行。
比如:
if __name__ == '__main__':
test()
3) 搜索路徑
Python模塊的導(dǎo)入會(huì)有一個(gè)路徑搜索的過程,如果這些搜索路徑都找不到的話,
會(huì)報(bào)ImportError,可以通過打印sys.path可以看到這些搜索路徑,比如我的:
如果你的模塊都不在這些路徑里,就會(huì)報(bào)錯(cuò),當(dāng)然也可以通過
sys.path.append("路徑") 把路徑添加到搜索路徑中!
4) 下載安裝第三方庫
方法一:Pycharm直接安裝
File -> Default Settings -> Project Interpreter -> 選擇當(dāng)前Python版本
可以看到當(dāng)前安裝的所有第三庫,點(diǎn)+號(hào)進(jìn)入庫搜索,在搜索頁找到想要的
庫后勾選點(diǎn)擊Install Package即可,點(diǎn)-號(hào)可以卸載不需要的庫。
方法二:命令行使用pip命令安裝
pip在Python3里就自帶了,在Python安裝目錄的Scripts文件夾下,
win上需要配置下環(huán)境變量才能使用:
Path后面加上這個(gè)路徑即可:
pip install 庫名 # 安裝
python3 -m pip install 庫名 # 作用同上,可以區(qū)分python2和python3而已
pip install --upgrade pip # 更新pip
pip uninstall 庫名 # 卸載庫
pip list # 查看已安裝庫列表
5) 讓別人使用你的模塊
當(dāng)你開始學(xué)爬蟲,電腦會(huì)慢慢多很多妹子圖,別問我為什么...
一些小伙伴看到會(huì)問你拿U盤拷,授之以魚不如授之以漁,直接把
自己寫的爬小姐姐的Py文件讓他自己跑,不更好~讓他裝玩Python3
配置好環(huán)境變量,直接命令行執(zhí)行Python xxx.py是會(huì)報(bào)模塊找
不到的,你的小伙伴僅僅是對(duì)小姐姐有興趣,對(duì)Py學(xué)習(xí)沒什么
興趣,你不可能讓他pip命令一個(gè)個(gè)裝,可不可以導(dǎo)出一個(gè)依賴
文件的東西,執(zhí)行以下自動(dòng)安裝模塊呢?答案肯定是可以的:
先pip命令安裝一波:pipreqs:pip install pipreqs
安裝完后打開終端,cd到需要導(dǎo)出的項(xiàng)目,鍵入:
pipreqs 導(dǎo)出到哪個(gè)目錄
就可以導(dǎo)出一個(gè)requirements.txt文件了,文件里就是你項(xiàng)目
用到的需要另外安裝的Py庫了,把這個(gè)文件發(fā)給你的小伙伴,讓他
命令行執(zhí)行:
pip install -r requirements.txt
運(yùn)行后把庫裝上就基本:
另外,如果是你想把自己Python環(huán)境里的所有包都遷移到另一臺(tái)電腦
可以使用:
pip freeze > requirements.txt
結(jié)語
呼,歷時(shí)兩周,總算把Python的基礎(chǔ)知識(shí)過了一遍,當(dāng)然肯定是會(huì)有遺漏的
后面想到再補(bǔ)上吧,擼基本知識(shí)是挺乏味的,期待后續(xù)爬蟲學(xué)習(xí)~
總結(jié)
以上是生活随笔為你收集整理的python bif_小猪的Python学习之旅 —— 1.基础知识储备的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cocos2d-x地图随精灵无限滚动与边
- 下一篇: 客服开场白话术