第1章 就這么愉快地開始吧
IDLE是一個python shell词渤,shell 的意思就是“外殼”猫妙,從基本上說尖昏,就是一個通過輸入文本與程序交互的途徑仰税。利用它,可以給操作系統(tǒng)下達(dá)命令抽诉≡纱兀可以利用IDLE這個shell與python進(jìn)行互動。
>>> 提示符
- 快捷鍵 Alt+N:復(fù)制上一條語句
- 快捷鍵 Alt+P:下一條語句
示例:
print("I love fishc.com")
print("I love fishc.com"*8)
print("well water" + "river")
print(5+3)
- 快捷鍵Ctrl+N:IDLE中新建一個文件
第2章 用python設(shè)計第一個游戲
縮進(jìn)是python的靈魂迹淌,縮進(jìn)的嚴(yán)格要求使得python的代碼顯得非常精簡并且有層次河绽。
Tab鍵,縮進(jìn)
BIF(built-in-functions)內(nèi)置函數(shù)
在IDLE中輸入dir(__bulitins__),可以看到python提供的內(nèi)置函數(shù)列表
唉窃。
help()這個BIF用于顯示BIF的功能描述耙饰。
第3章 成為高手前必須知道的一些基礎(chǔ)知識
3.1 變量
字符串的拼接:字符串+字符串
tips:
- 使用變量前,需要對其先賦值纹份。
- 變量名可以包括字母苟跪、數(shù)字、下劃線蔓涧,但變量名不能以數(shù)字開頭件已。
- 字母可以大寫和小寫,但大小寫是不同的元暴。
- 等號(=)是賦值的意思拨齐,左邊是名字,右邊是值昨寞。
- 變量的命名理論上可以取任何合法的名字,但作為一個優(yōu)秀的程序員厦滤,盡量給變量取一個專業(yè)一點兒的名字援岩。
3.2 字符串
字符串就是引號內(nèi)的一切東西,字符串也叫做文本掏导。
轉(zhuǎn)義符號(\)
'let\'s go'
"let's go"
3.3 原始字符串
可以用反斜杠對自身進(jìn)行轉(zhuǎn)義。
原始字符串,只需要在字符串前加一個英文字母r即可肺魁。
tips:
- 使用字符串時渺蒿,無論是否原始字符串,都不能以反斜杠作為結(jié)尾(反斜杠放在字符串的末尾表示該字符串還沒有結(jié)束值纱,換行繼續(xù)的意思鳞贷。)
3.4 長字符串
希望得到一個跨越多行的字符串:三重引號字符串
我愛魚C,
正如我愛小甲魚虐唠,
他那呱唧呱唧
呱唧呱唧
呱唧呱唧的聲音
總縈繞在我的腦海搀愧,
久久不肯散去…
tips:
- 切記:編程中使用的標(biāo)點符號都是英文的!
3.5 改進(jìn)我們的小游戲
3.6 條件分支
python的條件分支語句:
if 條件:
條件為真(True)執(zhí)行的操作
else:
條件為假(False)執(zhí)行的操作
改進(jìn):
if guess == 8:
print("我操,你是小甲魚心里的蛔蟲嗎咱筛?")
print("哼搓幌,猜中了也沒有獎勵!")
else:
if guess > 8:
print("哥迅箩,大了大了~")
else:
print("嘿溉愁,小了小了!饲趋!")
print("游戲結(jié)束拐揭,不玩啦~")
3.7 while循環(huán)
python的while循環(huán)
while 條件:
條件為真(True)執(zhí)行的操作
改進(jìn)
print("---------------我愛魚C工作室-------------------")
temp = input("不妨猜測一下小甲魚現(xiàn)在心里想的是哪個數(shù)字:")
guess = int(temp)
while guess != 8:
temp = input("哎呀,猜錯了篙贸,請重新輸入吧:")
guess = int(temp)
if guess == 8:
print("我操投队,你是小甲魚心里的蛔蟲嗎?")
print("哼爵川,猜中了也沒有獎勵敷鸦!")
else:
if guess > 8:
print("哥,大了大了~")
else:
print("嘿寝贡,小了小了0桥!")
print("游戲結(jié)束圃泡,不玩啦~")
and邏輯操作符
python的邏輯操作符可以將任意表達(dá)式連接在一起碟案,并得到一個布爾類型的值。布爾類型的值只有兩個:True和False
3.8 引入外援
random模塊颇蜡,random.randint()函數(shù)价说,返回一個隨機(jī)的整數(shù)。
import random
secret = random.randint(1,10)
print("---------------我愛魚C工作室-------------------")
temp = input("不妨猜測一下小甲魚現(xiàn)在心里想的是哪個數(shù)字:")
guess = int(temp)
while guess != secret:
temp = input("哎呀风秤,猜錯了鳖目,請重新輸入吧:")
guess = int(temp)
if guess == secret:
print("我操,你是小甲魚心里的蛔蟲嗎缤弦?")
print("哼领迈,猜中了也沒有獎勵!")
else:
if guess > secret:
print("哥碍沐,大了大了~")
else:
print("嘿狸捅,小了小了!累提!")
print("游戲結(jié)束尘喝,不玩啦~")
3.9 閑聊數(shù)據(jù)類型
python的數(shù)值類型包含:整型、浮點型刻恭、布爾類型瞧省、復(fù)數(shù)類型等
3.9.1 整型
3.9.2 浮點型
E記法扯夭,科學(xué)計數(shù)法
1.5e4 1.5x10^4
3.9.3 布爾類型
布爾類型可以當(dāng)做整數(shù)來對待,True相當(dāng)于整型值1鞍匾,F(xiàn)alse相當(dāng)于整型值0交洗,但把布爾類型當(dāng)成1和0來參與運(yùn)算這種做法是不妥的。
3.9.4 類型轉(zhuǎn)換
int()橡淑、 float() 构拳、str()
tips:
- 如果是浮點數(shù)轉(zhuǎn)換為整數(shù),python會采取“截斷”處理梁棠,就是把小數(shù)點后的數(shù)據(jù)直接砍掉置森,注意不是四舍五入!
3.9.5 獲取關(guān)于類型的信息
方式1:type()函數(shù)
方式2:isinstance()函數(shù)符糊,有兩個參數(shù)凫海,一個是待確定類型的數(shù)據(jù),一個是指定一個數(shù)據(jù)類型男娄。isinstance會根據(jù)兩個參數(shù)返回一個布爾類型的值行贪,True表示類型一致,F(xiàn)alse表示類型不一致模闲。
3.10 常用操作符
3.10.1 算術(shù)操作符
+ - * / %(取余) **(冪運(yùn)算操作符) //(地板除法)
+= -= *= /=
3.10.2 優(yōu)先級問題
3.10.3 比較操作符
< <= > >= == !=
3.10.4 邏輯操作符
and or not
第4章 了不起的分支和循環(huán)
其實建瘫,世界上根本沒有最優(yōu)秀的編程語言,只有最合適的語言尸折,面對不同的環(huán)境和需求啰脚,就會有不同的編程工具去迎合。
4.1 分支與循環(huán)
打飛機(jī)框架.py
加載背景音樂
播放背景音樂(設(shè)置單曲循環(huán))
我方飛機(jī)誕生
interval = 0
while True:
if 用戶是否點擊了關(guān)閉按鈕:
退出程序
interval += 1
if interval == 50:
interval = 0
小飛機(jī)誕生
小飛機(jī)移動一個位置
屏幕刷新
if 用戶鼠標(biāo)產(chǎn)生移動:
我方飛機(jī)中心位置 = 用戶鼠標(biāo)位置
屏幕刷新
if 我方飛機(jī)與小飛機(jī)發(fā)生肢體沖突:
我方掛实夹,播放撞機(jī)音樂
修改我方飛機(jī)圖案
打印"game over"
停止背景音樂橄浓,最好淡出
4.2 課堂小練習(xí)
判斷和循環(huán),判斷就是應(yīng)不應(yīng)該做某事亮航,循環(huán)就是持續(xù)做某事贮配。條件分支,就是判斷塞赂,習(xí)慣用到的是if-else的搭配,循環(huán)就用while.
4.3 結(jié)果分析
判斷會消耗CPU時間
要實現(xiàn)一個程序事實上并不難昼蛀,但作為一個優(yōu)秀的程序員宴猾,你必須要形成良好的編程思維。
4.4 python可以有效避免“懸掛else”
初學(xué)C語言的朋友很容易被以下代碼欺騙
if (hi > 2)
if (hi > 7)
printf("好棒叼旋!好棒仇哆!")
else
printf("切~")
在這個例子中,雖然else是想和外層的if匹配夫植,但事實上按照C語言的就近匹配原則這個else是屬于內(nèi)層if的讹剔。由于初學(xué)者的一不小心油讯,就容易導(dǎo)致BUG的出現(xiàn),這就是著名的懸掛else延欠。
python的縮進(jìn)使用強(qiáng)制規(guī)定
4.5 條件表達(dá)式(三元操作符)
“多少元”操作符的意思是這個操作符有多少個操作數(shù)陌兑。賦值操作符“=”是二元操作符,所以它有左邊和右邊兩個操作數(shù)由捎,“-”是一元操作符兔综,表示負(fù)號,只有一個操作數(shù)狞玛。
if x < y:
small = x
else:
small = y
三元操作符語法
a = x if x < y else y
改進(jìn)
small = x if x < y else y
4.6 斷言
斷言(assert)這個關(guān)鍵字稱為“斷言”软驰,當(dāng)這個關(guān)鍵字后邊的條件為假的時候,程序自動崩潰并拋出AssertionError異常心肪。
什么情況下需要這樣的代碼呢锭亏?當(dāng)我們在測試程序的時候與其讓錯誤的條件導(dǎo)致程序今后莫名其妙地崩潰,不如在錯誤條件出現(xiàn)的那一瞬間實現(xiàn)“自爆”硬鞍。
一般來說慧瘤,可以用它在程序中置入檢查點,當(dāng)需要確保程序中的某個條件一定為真才能讓程序正常工作時膳凝,assert關(guān)鍵字就非常有用了碑隆。
4.7 while循環(huán)語句
python的while循環(huán)跟if條件分支類似,在條件為真的情況下蹬音,執(zhí)行一段代碼上煤,不同的是,只要條件為真著淆,while循環(huán)會一直重復(fù)執(zhí)行那段代碼劫狠,把這段代碼稱為循環(huán)體。
while條件:
循環(huán)體
4.8 for循環(huán)語言
python的計數(shù)器循環(huán)永部,for循環(huán)独泞。
語法:
for 目標(biāo) in 表達(dá)式:
循環(huán)體
4.9 range()
語法:
range([start,]stop[,step=1])
range()可以說是跟for循環(huán)最合適做搭檔的小伙伴。
4.10 break語句
break語句的作用是終止當(dāng)前循環(huán)苔埋,跳出循環(huán)體懦砂。
bingo = "小甲魚是帥哥"
answer = input("請輸入小甲魚最想聽的一句話:")
while True:
if answer == bingo:
break
answer = input("抱歉,錯了组橄,請重新輸入(答案正確才能退出游戲):")
print("哎呦荞膘,帥哦~")
print("您真是小甲魚肚子里的蛔蟲啊~")
4.11 continue語句
continue語句的作用是終止本輪循環(huán)并開始下一輪循環(huán)(注意:在開始下一輪循環(huán)之前,會先測試循環(huán)條件)玉工。
第5章 列表羽资、元組和字符串
5.1 列表:一個“打了激素”的數(shù)組
5.1.1 創(chuàng)建列表
number = [1,2,3,4,5,6]
member = ['小甲魚','小布丁','黑夜','迷途','意境']
mix = [1,"小甲魚",3.14,[1,2,3]]
empty = []
5.1.2 向列表添加元素
append()方法不是一個BIF,它是屬于列表對象的一個方法遵班。
屬于對象的函數(shù)稱為方法屠升。
方法1:append()方法
方法2:extend()方法潮改,extend()方法事實上使用一個列表來拓展另一個列表,所以它的參數(shù)應(yīng)該是一個列表腹暖。
方法3:insert()方法
tips:
- 凡是順序索引汇在,python均從0開始,同時這也是大多數(shù)編程語言約定俗成的規(guī)范微服。
5.1.3 從列表中獲取元素
通過元素的索引值(index)從列表中獲取單個元素趾疚,注意,列表索引值是從0開始的以蕴。
5.1.4 從列表刪除元素
方法1:remove()糙麦,參數(shù)是元素的名字
方法2:del,del是一個語句丛肮,不是一個列表的方法赡磅,所以不必在它后邊加上小括號()。如果想刪除整個列表宝与,可以直接用del加列表名刪除焚廊。
方法3:pop(),pop()方法默認(rèn)是彈出列表中的最后一個元素。當(dāng)為它加上一個索引值作為參數(shù)的時候习劫,它會彈出這個索引值對應(yīng)的元素咆瘟。
5.1.5 列表分片
列表分片就是建立原列表的一個拷貝(或者說副本),所以如果你想對列表做出某些修改诽里,但同時還想保持原來的那個列表袒餐,就直接使用分片的方法。
5.1.6 列表分片的進(jìn)階玩法
5.1.7 一些常用操作符
當(dāng)列表中包含多個元素時谤狡,默認(rèn)從第一個元素開始比較灸眼,只要有1個PK贏了,就算整個列表贏了墓懂。字符串比較同理(字符串比較的是第一個字符對應(yīng)的ASCII碼值的大醒嫘)。
加號(+)也叫連接操作符捕仔,可把多個列表對象合并在一起匕积,相當(dāng)于extend()方法實現(xiàn)的效果,一般情況下建議大家使用extend()方法來擴(kuò)展列表榜跌,這樣顯得更為規(guī)范和專業(yè)闸天。另外,連接操作符并不能實現(xiàn)列表添加新元素的操作斜做。
乘號(*)也叫重復(fù)操作符
成員關(guān)系操作符 in 、not in
5.1.8 列表的小伙伴們
count()方法的作用是計算它的參數(shù)在列表中出現(xiàn)的次數(shù)
index()方法返回它的參數(shù)在列表中的位置
reverse()方法的作用是將整個列表原地翻轉(zhuǎn)湾揽,改變了列表
sort()方法用指定的方式對列表的成員進(jìn)行排序瓤逼,默認(rèn)不需要參數(shù)笼吟,從小到大排序。sort(func,key,reverse)
sort(reverse= True)反向排序
5.1.9 關(guān)于分片“拷貝”概念的補(bǔ)充
- END - 2019/4/20 23:18
5.2 元組:戴上了枷鎖的列表
元組和列表最大的區(qū)別就是你可以任意修改列表中的元素霸旗,可以任意插入或者刪除一個元素贷帮,而對元組是不行的,元組是不可改變的诱告。
5.2.1 創(chuàng)建和訪問一個元組
創(chuàng)建列表用的是中括號[]撵枢,而創(chuàng)建元組大部分時候用的是小括號()(注意:這里說的是大部分)。
列表的標(biāo)志性符號是中括號([ ])精居,那么元組的標(biāo)志性符號是什么锄禽?
小括號呀 ×
就算沒有小括號,temp還是元組類型靴姿,所以逗號(沃但,)才是關(guān)鍵,小括號只是起到補(bǔ)充的作用佛吓。如果想要創(chuàng)建一個空元組宵晚,直接使用小括號即可。
tips
-
如果要創(chuàng)建的元組中只有一個元素维雇,請在它后邊加上一個逗號(淤刃,),這樣可以明確告訴python你要的是一個元組吱型。
5.2.2 更新和刪除元組
如何更新一個字符串的逸贾?通過拷貝現(xiàn)有的字符串片段構(gòu)造一個新的字符串的方式解決,對元組也是使用同樣的方法唁影。
通過分片的方法讓元組拆分成兩部分耕陷,然后使用連接操作符(+)合并成一個新元組,最后將原來的變量名指向連接好的新元組据沈。逗號是必須的哟沫,小括號也是必須的。
要刪除整個元組锌介,只要使用del語句即可顯式地刪除一個元組吓肋。但日常使用中冷冗,很少使用del去刪除整個元組,因為python的回收機(jī)制會在這個元組不再被使用到的時候自動刪除。
5.3 字符串
tips:
- 通過拼接舊字符串的各個部分得到新字符串的方式并不是真正意義上的改變了原始字符串芬骄,原來的那個字符串還在,只是將變量指向了新的字符串(舊的字符串一旦失去了變量的引用狠半,就會被python的垃圾回收機(jī)制釋放掉)可缚。
5.3.1 各種內(nèi)置方法
字符串的方法及注釋https://fishc.com.cn/thread-38992-1-1.html
5.3.2 格式化
格式化字符串就是按照統(tǒng)一的規(guī)格去輸出一個字符串。
1.format()
format()方法接受位置參數(shù)和關(guān)鍵字參數(shù)温自,二者均傳遞到一個叫做replacement字段松捉,而這個replacement字段在字符串內(nèi)由大括號({})表示。
tips:
-
將位置參數(shù)和關(guān)鍵字參數(shù)綜合在一起使用馆里,那么位置參數(shù)必須在關(guān)鍵字參數(shù)之前隘世,否則會出錯。
位置參數(shù)“不打印”沒有被輸出鸠踪,這是因為{0}的特殊功能被外層的大括號{}剝奪丙者,因此沒有字段可以輸出。
在替換域中慢哈,冒號表示格式化符號的開始蔓钟,“.1”的意思是四舍五入到保留1位小數(shù)點,f的意思是浮點數(shù)。
2.格式化操作符:%
字符串獨享的一個操作符:%
當(dāng)%左右均為數(shù)字的時候,它表示求余數(shù)的操作;但當(dāng)它出現(xiàn)在字符中的時候臀玄,它表示的是格式化操作符累贤。
3.python的轉(zhuǎn)義字符集含義
5.4 序列
列表、元組和字符串的共同點:
- 都可以通過索引得到每一個元素
- 默認(rèn)索引值總是從0開始
- 可以通過分片的方法得到一個范圍內(nèi)的元素的集合
- 有很多共同的操作符(重復(fù)操作符、拼接操作符、成員關(guān)系操作符)
統(tǒng)稱為:序列
1. list([iterable])
list()方法用于把一個可迭代對象轉(zhuǎn)換為列表。
迭代,就是重復(fù)反饋過程的活動,其目的通常是為了接近并達(dá)到所需的目標(biāo)或結(jié)果。每一次對過程的重復(fù)過程被稱為一次“迭代”,而每一次迭代得到的結(jié)果會被用來作為下一次迭代的初始值……,就目前來說,迭代就是一個for循環(huán)。
2. tuple([iterable])
tuple()方法用于把一個可迭代對象轉(zhuǎn)換為元組,具體用法與list()一樣。
3. str(obj)
str()方法吧obj對象轉(zhuǎn)換為字符串。
4. len(sub)
len()方法用于返回sub參數(shù)的長度。
5. max(```)
max()方法用于返回序列或參數(shù)集合中的最大值。
6. min(```)
min()方法用于返回序列或參數(shù)集合中的最小值。
tips:
- 使用max()和min()方法都要保證序列或參數(shù)的數(shù)據(jù)類型統(tǒng)一,否則會出錯。
7. sum(iterable[,start])
sum()方法用于返回序列iterable的綜合,可選參數(shù)strat,如果設(shè)置該參數(shù),表示從該值開始加起,默認(rèn)值是0.
8. sorted(iterable,key=None,reverse=False)
sorted()方法用于返回一個排序的列表,列表的內(nèi)置方法sort()是實現(xiàn)列表原地排序;而sorted()是返回一個排序后的新列表。
9. reversed(sequence)
reversed()方法用于返回逆向迭代序列的值。實現(xiàn)效果跟列表的內(nèi)置方法reverse()一致,區(qū)別是列表的內(nèi)置方法是原地翻轉(zhuǎn),而reversed()是返回一個翻轉(zhuǎn)后的迭代器對象候址。
10. enumerate(iterable)
enumerate()方法生成由二元組(二元組就是元素數(shù)量為二的元組)構(gòu)成的一個迭代對象,每個二元組是由可迭代參數(shù)的索引號及其對應(yīng)的元素組成的。
11. zip(iter1[,iter2[```]])
zip()方法用于返回由各個可迭代參數(shù)共同組成的元組嘱蛋。
第6章 函數(shù)
6.1 python的樂高積木
優(yōu)秀的東西永遠(yuǎn)是經(jīng)典的凶伙,而經(jīng)典的東西永遠(yuǎn)是簡單的。要能夠把復(fù)雜的東西簡單化才能成為經(jīng)典。
為了使得程序的代碼更為簡單,需要把程序分解成較小的組成部分沉迹。這里通過三種方式來實現(xiàn):函數(shù)葫松、對象和模塊珊擂。
6.1.1 創(chuàng)建和調(diào)用函數(shù)
函數(shù)就是把代碼打包成不同形狀的樂高積木挚歧,以便可以發(fā)揮想象力進(jìn)行隨意拼裝和反復(fù)使用。
在python中創(chuàng)建一個函數(shù)用def關(guān)鍵字,在函數(shù)名后邊要加上一對小括號,必不可少。
6.1.2 函數(shù)的參數(shù)
使用多個參數(shù)猫态,只需要用逗號隔開即可疚膊。
6.1.3 函數(shù)的返回值
6.2 靈活即強(qiáng)大
靈活表現(xiàn)為多變
6.2.1 形參和實參
形式參數(shù)(parameter)和實際參數(shù)(argument)
6.2.2 函數(shù)文檔
給函數(shù)寫文檔是為了讓別人可以更好地理解你的函數(shù)傀蚌。
- 函數(shù)的文檔字符串可以通過特殊屬性_doc_獲取销部。
- 想用一個函數(shù)卻不確定其用法的時候,會通過help()函數(shù)來查看函數(shù)的文檔。
image.png
6.2.3 關(guān)鍵字函數(shù)
6.2.4 默認(rèn)參數(shù)
默認(rèn)參數(shù)是在定義的時候賦予了默認(rèn)值的參數(shù)。
6.2.5 收集參數(shù)
也叫可變參數(shù),在參數(shù)前邊加上星號(*)即可。
tips:
- python把標(biāo)志為收集參數(shù)的參數(shù)們打包成一個元組。
- 如果在收集參數(shù)后邊還需要指定其他參數(shù)颊埃,在調(diào)用函數(shù)的時候就應(yīng)該使用關(guān)鍵字參數(shù)來指定肥败,否則python就會把你的實參都列入收集參數(shù)的范疇纽谒。
-
如果你的參數(shù)中帶有收集參數(shù)不见,可將其他參數(shù)設(shè)置為默認(rèn)參數(shù)。
image.png
6.3 我的地盤聽我的
6.3.1 函數(shù)和過程
在很多編程語言中酪惭,函數(shù)和過程其實是分開的。一把認(rèn)為函數(shù)(function)是有返回值的,而過程(procedure)是簡單、特殊并且沒有返回值的撵溃。
python嚴(yán)格來說只有函數(shù)语淘,沒有過程吕粗。python的所有函數(shù)都有返回值输枯。
6.3.2 再談?wù)劮祷刂?/h3>
image.png
6.3.3 函數(shù)變量的作用域
在函數(shù)里邊定義的參數(shù)以及變量,都稱為局部變量缎讼。出了這個函數(shù)夹纫,這些變量都是無效的月匣。事實上 的原理是,python在運(yùn)行函數(shù)的時候,利用棧進(jìn)行存儲,當(dāng)執(zhí)行完該函數(shù)后,函數(shù)中的所有數(shù)據(jù)都會被自動刪除。所以在函數(shù)外邊是無法訪問函數(shù)內(nèi)部的局部變量的。
全局變量
如果在函數(shù)內(nèi)部試圖修改全局變量盒延,那么python會創(chuàng)建一個新的局部變量替代,但真正的全局變量時不變的。
可以在函數(shù)內(nèi)部訪問全局變量。
6.4 內(nèi)嵌函數(shù)和閉包
6.4.1 global關(guān)鍵字
全局變量的作用域是整個模塊(整個代碼段),也就是代碼段內(nèi)所有的函數(shù)內(nèi)部都可以訪問到全局變量椭蹄。但在函數(shù)內(nèi)部僅僅去訪問全局變量就好翼馆,不要試圖去修改它中姜。
python會使用屏蔽的方式“保護(hù)”全局變量:一旦函數(shù)內(nèi)部試圖修改全局變量受扳,python就會在函數(shù)內(nèi)部自動創(chuàng)建一個名字一模一樣的局部變量华望,這樣修改的結(jié)果只會修改到局部變量,而不會影響到全局變量裕偿。
6.4.2 內(nèi)嵌函數(shù)
python的函數(shù)定義是可以嵌套的焦人,也就是允許在函數(shù)內(nèi)部創(chuàng)建另一個函數(shù),這種函數(shù)叫做內(nèi)嵌函數(shù)或內(nèi)部函數(shù)。
6.4.3 閉包(closure)
閉包是函數(shù)式編程的一個重要的語法結(jié)構(gòu),函數(shù)式編程是一種編程范式。
python中的閉包從表現(xiàn)形式上定義為:如果在一個內(nèi)部函數(shù)里嘱根,對在外部作用域(但不是在全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包。
如果在一個內(nèi)部函數(shù)里(FunY就是這個內(nèi)部函數(shù))對外部作用域(但不是在全局作用域)的變量進(jìn)行引用(x就是被引用的變量,x在外部作用域FunX函數(shù)里,但不在全局作用域里)膊升,則這個內(nèi)部函數(shù)(FunY)就是一個閉包债查。
- 閉包的概念是由內(nèi)部函數(shù)而來的速和,所以不能在外部函數(shù)以外的地方對內(nèi)部函數(shù)及進(jìn)行調(diào)用吭敢。
- 在閉包中,外部函數(shù)的局部變量對應(yīng)內(nèi)部函數(shù)的局部變量,事實上相當(dāng)于之前將的全局變量跟局部變量的對應(yīng)關(guān)系块蚌,在內(nèi)部函數(shù)中,你只能對外部函數(shù)的局部變量進(jìn)行訪問,但不能進(jìn)行修改。
image.png
python認(rèn)為在內(nèi)部函數(shù)的x是局部變量的時候闹获,外部函數(shù)的x就被屏蔽了沙庐。
image.png
通過容器類型來存放铸抑,因為容器類型不是存放在棧里,所以不會被“屏蔽”掉。字符串、列表、元組,這些什么都可以往里放的就是容器類型。
如果希望在內(nèi)部函數(shù)里可以修改外部函數(shù)里的局部變量的值缝裁,使用關(guān)鍵字nonlocal。
image.png
6.5 lambda表達(dá)式
python的lambda表達(dá)式語法非常精簡首量,基本語法是在冒號(:)左邊放原函數(shù)的參數(shù)拣宏,可以有多個參數(shù)市俊,用逗號(绅你,)隔開即可领炫;冒號右邊是返回值砚哗。
lambda語句時間上是返回一個函數(shù)對象,如果要對它進(jìn)行使用仅淑,只需要進(jìn)行簡單的賦值操作即可称勋。
介紹兩個BIF:filter()和map()
1. filter()
filter有兩個參數(shù)。第一參數(shù)可以是函數(shù)也可以是None烘嘱,如果是一個函數(shù)的話纹因,則將第二個可迭代數(shù)據(jù)里的每一個元素作為函數(shù)的參數(shù)進(jìn)行計算浪讳,把返回True的值篩選出來猖腕;如果第一個參數(shù)是None镜廉,則直接將第二個參數(shù)中為True的值篩選出來。
2.map()
在編程領(lǐng)域,map()一般做“映射”來解釋。map()也有兩個參數(shù),仍然是一個函數(shù)和一個可迭代序列丁稀,將序列中的每一個元素作為函數(shù)的參數(shù)進(jìn)行運(yùn)算加工棘捣,直到可迭代序列每個元素都加工完畢仑荐,返回所有加工后的元素構(gòu)成的新序列子檀。
6.6 遞歸
6.6.1 遞歸是“神馬”
遞歸是算法的范疇奥务。
python3衙荐,對遞歸的深度默認(rèn)限制是100層。
6.6.2 寫一個求階乘的函數(shù)
6.6.3 這幫小兔崽子
6.6.4 漢諾塔
第7章 字典和集合
7.1 字典:當(dāng)索引不好用時
鍵(key) 值(value)
字典是python中唯一的映射類型,映射是數(shù)學(xué)上的一個術(shù)語碍论。
7.1.1 創(chuàng)建和訪問字典
字典的標(biāo)志性符號是大括號{}胎撤,字典由多個鍵和值共同構(gòu)成,每一對鍵值組合成為項锨匆。
字典跟序列不同,序列講究順序钥飞,字典講究映射博肋,不講順序。
要聲明一個空字典,直接用個大括號即可脱篙。
可以用dict()來創(chuàng)建字典
注意鍵的位置不能加上字符串的引號斤葱,否則會報錯夫啊。
- END - 2019/4/21 20:55
7.1.2 各種內(nèi)置方法
字典是python中唯一的映射類型赤套,字典不是序列。
1. fromkeys()
fromkeys()方法用于創(chuàng)建并返回一個新的字典北戏,它有兩個參數(shù):第一個參數(shù)是字典的鍵掌挚;第二個參數(shù)是可選的,是傳入鍵對應(yīng)的值谤饭。如果不提供标捺,默認(rèn)是None。
2. keys()揉抵、values()和items()
訪問字典的方法有keys()亡容、values()和items().
- keys()用于返回字典中的鍵;
- values()用于返回字典中的所有值冤今;
- items()用于返回字典中所有的鍵值對(也就是項)闺兢。
3. get()
get()方法提供了更寬松的方式去訪問字典項,當(dāng)鍵不存在的時候戏罢,get()方法并不會報錯屋谭,知識默默地返回了一個None。
4. copy()
copy()方法是復(fù)制字典帖汞。淺拷貝戴而。淺拷貝和直接復(fù)制不一樣。
5. pop()和popitem()
pop()是給定鍵彈出對應(yīng)的值翩蘸,而popitem()是彈出一個項所意。
setdefault()方法
和get()方法類似,但setdefault()在字典中找不到相應(yīng)的鍵時會自動添加催首。
6. update()
update()可以用來更新字典扶踊。
7.2 集合:在我的世界里,你就是唯一
集合在python中幾乎起到的所有作用就是:唯一郎任。
集合是無序的秧耗,你不能試圖去索引集合中的某一個元素。
7.2.1 創(chuàng)建集合
創(chuàng)建集合的2種方法:1)直接把一堆元素用大括號{}括起來舶治;2)用set()
去掉列表中重復(fù)的元素
7.2.2 訪問集合
- 由于集合中的元素時無序的分井,所以并不能像序列那樣用下標(biāo)來進(jìn)行訪問,但是可以使用迭代把集合中數(shù)據(jù)一個個讀取出來
- 可以用in和not in判斷一個元素是否在集合中已經(jīng)存在
-
使用add()方法可以為集合添加元素霉猛,使用remove()方法可以刪除集合中已知的元素尺锚。
image.png
7.2.3 不可變集合
使用frozenset()函數(shù)定義不可變集合。
第8章 永久存儲
編寫代碼的時候惜浅,操作系統(tǒng)為了更快的做出響應(yīng)瘫辩,把所有當(dāng)前的數(shù)據(jù)都放在內(nèi)存中,因為內(nèi)存和CPU數(shù)據(jù)傳輸?shù)乃俣纫仍谟脖P和CPU之間傳輸?shù)乃俣瓤旌芏唷5珒?nèi)存有一個天生的不足伐厌,一旦斷電就沒戲承绸,所以,請隨時使用快捷鍵Ctrl+C
8.1.1 打開文件
使用open()成功打開一個文件之后挣轨,它會返回一個文件對象军熏,拿到這個文件對象,就可以讀取或修改這個文件刃唐。
8.1.2 文件對象的方法
- END - 2019/4/22 23:24
8.1.3 文件的關(guān)閉
python擁有垃圾回收機(jī)制羞迷,會在文件對象的引用計數(shù)降至0的時候自動關(guān)閉文件界轩,所以在python編程李画饥,如果忘記關(guān)閉文件并不會造成內(nèi)存泄漏那么危險的結(jié)果。
8.1.4 文件的讀取和定位
文件的讀取方法很多浊猾,可以使用文件對象的read()和readline()方法抖甘,也可直接list(f)或者直接使用迭代來讀取。read()是按字節(jié)為單位讀取葫慎,如果不設(shè)置參數(shù)衔彻,那么會全部讀取出來,文件指針指向文件末尾偷办。tell()方法可以告訴你當(dāng)前指針的位置艰额。
文件指針可以認(rèn)為它是一個“書簽”太示,起到定位的作用杭措。使用seek()方法可以調(diào)整文件指針的位置。
seek(offset,from)方法有兩個參數(shù)盟广,表示從from(0代表文件起始位置废岂,1代表當(dāng)前位置祖搓,2代表文件末尾)偏移offset字節(jié)。
將文件指針設(shè)置到文件起始位置湖苞,使用seek(0,0)拯欧。
readline()方法用于在文件中讀取一整行,就是從文件指針的位置向后讀取财骨,直到遇到換行符(\n)結(jié)束镐作。
文件對象本身是支持迭代的,直接使用for語句把內(nèi)容迭代讀取即可隆箩。
8.1.5 文件的寫入
如果要寫入文件该贾,請確保之前的打開模式有‘w’或'a',否則會出錯摘仅。
使用'w'模式寫入文件靶庙,此前的文件內(nèi)容會被全部刪除。
如果要在原來的內(nèi)容上追加,一定要使用'a'模式打開文件六荒。
8.1.6 一個任務(wù)
tes_1.py
f = open(r'C:\Users\22254\Desktop\零基礎(chǔ)入門學(xué)習(xí)python-work\record2.txt')
boy = []
girl = []
count = 1
for each_line in f:
if each_line[:6] != '======':
# 我們這里進(jìn)行字符串分隔操作
(role,line_spoken) = each_line.split(':',1)
if role == '小甲魚':
boy.append(line_spoken)
if role == '小客服':
girl.append(line_spoken)
else:
# 文件的分別保存操作
file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'
boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')
boy_file.writelines(boy)
girl_file.writelines(girl)
boy_file.close()
girl_file.close()
boy = []
girl = []
count += 1
file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'
boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')
boy_file.writelines(boy)
girl_file.writelines(girl)
boy_file.close()
girl_file.close()
f.close()
tes_2.py
def save_file(boy,girl,count):
file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'
boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')
boy_file.writelines(boy)
girl_file.writelines(girl)
boy_file.close()
girl_file.close()
def split_file(file_name):
f = open(r'C:\Users\22254\Desktop\零基礎(chǔ)入門學(xué)習(xí)python-work\record2.txt')
boy = []
girl = []
count = 1
for each_line in f:
if each_line[:6] != '======':
# 我們這里進(jìn)行字符串分隔操作
(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('record2.txt')
8.2 文件系統(tǒng):介紹一個高大上的東西
模塊是一個包含所有你定義的函數(shù)和變量的文件护姆,后綴名是.py。模塊可以被別的程序引入掏击,以使用該模塊中的函數(shù)等功能卵皂。
OS模塊(operating system),操作系統(tǒng)。OS模塊高大上砚亭,是因為對于文件系統(tǒng)的訪問灯变,python一般是通過OS模塊來實現(xiàn)的。
常用的操作系統(tǒng)windows/Mac OS/Linux/UNIXdeng ,這些操作系統(tǒng)底層對于文件系統(tǒng)的訪問工作原理是不同的捅膘,因此你可能就要針對不同的系統(tǒng)來考慮使用哪些文件系統(tǒng)模塊添祸。
但python是跨平臺的語言,同樣的源代碼在不同的操作系統(tǒng)不需要修改就可以同樣實現(xiàn)寻仗。有了OS模塊刃泌,不需要關(guān)心什么操作系統(tǒng)下使用什么模塊,OS模塊會幫你選擇正確的模塊并調(diào)用署尤。
1. getcwd()
有些情況需要獲得應(yīng)用程序當(dāng)前的工作目錄(比如要保存臨時文件)
2.chdir(path)
用chdir()函數(shù)可以改變當(dāng)前工作目錄
3. listdir(path='.')
列舉指定目錄中的文件名(‘.’表示根目錄耙替,‘..’表示上一級目錄)
8.3 pickle:腌制一缸美味的泡菜
pickle模塊幾乎可以把所有python的對象都轉(zhuǎn)化為二進(jìn)制的形式存放,這個過程稱為pickling,那么從二進(jìn)制形式轉(zhuǎn)換回對象的過程稱為unpickling.
使用dump方法來保存數(shù)據(jù)曹体。
第9章 異常處理
9.1 你不可能總是對的
作為一個合格的程序員俗扇,在編程的時候一定要意識到一點,就是永遠(yuǎn)不要相信你的用戶箕别,要把他們想象成熊孩子铜幽,把他們想象成黑客,他們總是想要搞掉你的程序究孕,這樣你寫出來的程序自然就會更加安全和穩(wěn)定啥酱。
程序出現(xiàn)邏輯錯誤或用戶輸入不合法都會引發(fā)異常,但這些異常并不是致命的厨诸,不會導(dǎo)致程序崩潰死掉镶殷。可以利用python提供的異常處理機(jī)制微酬,在異常出現(xiàn)的時候及時捕獲绘趋,并從內(nèi)部自我消化掉。
1. AssertionError:斷言語句(assert)失敗
當(dāng)Assert這個關(guān)鍵字后邊的條件為假的時候陷遮,程序?qū)⑼V共伋鯝ssertionError異常。assert語句一般是在測試程序的時候用于在代碼中置入檢查點垦江。
2. AttributeError:嘗試訪問未知的對象屬性
當(dāng)試圖訪問的對象屬性不存在時拋出的異常
3. IndexError:索引超出序列的范圍
4. KeyError:字典中查找一個不存在的關(guān)鍵字
建議使用dict.get()方法
5. NameError:嘗試訪問一個不存在的變量
6. OSError:操作系統(tǒng)產(chǎn)生的異常
OSError是操作系統(tǒng)產(chǎn)生的異常帽馋,像打開一個不存在的文件會引發(fā)FileNotFoundError(是OSError的子類)。
7. SyntaxError:python的語法錯誤
8. TypeError:不同類型間的無效操作
9. ZeroDivisionError:除數(shù)為零
異常捕獲可以使用try語句來實現(xiàn),任何出現(xiàn)try語句范圍內(nèi)的異常都會被及時捕獲到绽族。try語句有兩種實現(xiàn)方式:try-except; try-finally
9.2 try-except語句
使用as把具體的錯誤信息打印出來姨涡。
9.2.1 針對不同異常設(shè)置多個except
9.2.2 對多個異常統(tǒng)一處理
9.2.3 捕獲所有異常
…
except:
print('出錯啦')
…
不建議,會隱藏所有程序員未想到并且未做好準(zhǔn)備的錯誤吧慢,例如當(dāng)用戶輸入Ctrl+C試圖終止程序涛漂,卻被解釋為KeyboardInterrupt異常。
注意:try語句檢測范圍一旦出現(xiàn)異常检诗,剩下的語句將不會被執(zhí)行匈仗。
9.3 try-finally語句
如果try語句塊中沒有任何運(yùn)行時錯誤,會跳過except語句塊執(zhí)行finally語句塊的內(nèi)容逢慌。如果出現(xiàn)異常悠轩,則會先執(zhí)行except語句塊的內(nèi)容再執(zhí)行finally語句塊的內(nèi)容√檠ⅲ總之哗蜈,finally語句塊中的內(nèi)容就是確保無論如何都將被執(zhí)行的內(nèi)容。
9.4 raise語句
9.5 豐富的else語句
1. 要么怎樣坠韩,要么不怎樣
典型的if-else語句
2. 干完了能怎樣,干不完就別想怎樣
else可以跟for while循環(huán)語句配合使用炼列,但else語句塊只在循環(huán)完成后執(zhí)行只搁,也就是說,如果循環(huán)中使用break語句跳出循環(huán)俭尖,那么else里邊的內(nèi)容就不會被執(zhí)行了氢惋。
3. 沒有問題?那就干吧
else語句還能跟異常處理進(jìn)行搭配稽犁。只要try語句塊沒有出現(xiàn)異常焰望,就會執(zhí)行else語句塊中的內(nèi)容。
9.6 簡潔的with語句
with會自動幫你關(guān)閉文件已亥。
第10章 圖形用戶界面入門
10.1 導(dǎo)入EasyGui
10.2 使用EasyGui
10.3 修改默認(rèn)設(shè)置
《EasyGui學(xué)習(xí)文檔》https://fishc.com.cn/forum.php?mod=viewthread&tid=46069&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
第11章 類和對象
11.1 給大家介紹對象
封裝熊赖,把亂七八糟的數(shù)據(jù)扔進(jìn)列表里,這是一種封裝虑椎,是數(shù)據(jù)層面的封裝震鹉;把常用的代碼段打包成一個函數(shù),這也是一種封裝捆姜,是語句層面的封裝传趾。對象,也是一種封裝的思想泥技。對象的來源是模擬真實世界浆兰,把數(shù)據(jù)和代碼都封裝在一起了。
11.2 對象 = 屬性 + 方法
一個對象的特征稱為屬性(特征的描述稱為屬性,在代碼層面來看其實就是變量)簸呈,一個對象的行為稱為方法(方法其實就是函數(shù)宽涌,通過調(diào)用這些函數(shù)來完成某些工作)。
定義了對象的特征(屬性)和行為(方法)蝶棋,但還不是一個完整的對象卸亮,將定義的這些稱為類(Class)。需要使用類來創(chuàng)建一個真正的對象玩裙,這個對象就叫做這個類的一個實例兼贸,也叫做實例對象。
創(chuàng)建一個對象吃溅,叫做類的實例化溶诞。
11.3 面向?qū)ο缶幊?/h2>
多態(tài)就是不同對象對同一方法響應(yīng)不同的行動
11.3.1 self是什么
python的self相當(dāng)于C++的this指針。
把類比作是圖紙决侈,由類實例化后的對象才是真正可以住人的房子螺垢。根據(jù)一張圖紙可以設(shè)計除成千上萬的房子,都長得差不多赖歌,但是他們都有不同的主人枉圃。每個人都只能回到自己注的房子,所以self相當(dāng)于每個房子的門牌號庐冯,有了self孽亲,就可以輕松找到自己的房子。
python的self參數(shù)同理展父,由同一個類可以生成無數(shù)對象返劲,當(dāng)一個對象的方法被調(diào)用的時候,對象會將自身的引用作為第一個參數(shù)傳給該方法栖茉,那么python就知道需要操作哪個對象的方法了篮绿。
11.3.2 你聽說過python的魔法方法嗎
特殊方法:_init()稱為構(gòu)造方法,_init()方法的魔力體現(xiàn)在只要實例化一個對象吕漂,這個方法就會在對象被創(chuàng)建時自動調(diào)用亲配。實例化對象時是可以傳入?yún)?shù)的,這些參數(shù)會自動傳入_init_()方法中痰娱,可以通過重寫這個方法來自定義對象的初始化操作弃榨。
11.3.3 公有和私有
默認(rèn)上對象的屬性和方法都是公開的,可以通過點操作符(.)進(jìn)行訪問梨睁。
為了實現(xiàn)類似私有變量的特征鲸睛,python內(nèi)部采用了一種叫name mangling(名字改編)的技術(shù),在python中定義私有變量只需要在變量名或函數(shù)名前加上“__”兩個下劃線坡贺,那么這個函數(shù)或變量就會變成私有的了官辈。
python動了手腳箱舞,把雙下橫線開頭的變量進(jìn)行了改名。實際上在外部使用“_類名__變量名”即可訪問雙下橫線開頭的私有變量拳亿。
注:python目前的私有機(jī)制其實是偽私有的晴股,python的類沒有權(quán)限控制的,所有變量都是可以被外部調(diào)用的肺魁。
11.4 繼承
語法:
class 類名(被繼承的類):
被繼承的類稱為基類电湘、父類或超類;繼承者稱為子類鹅经,一個子類可以繼承它的父類的任何屬性和方法寂呛。
注意:如果子類中定義與父類同名的方法或?qū)傩裕瑒t會自動覆蓋父類對應(yīng)的方法或?qū)傩浴?br>
異常:Shark對象沒有x屬性瘾晃。原因:在Shark類中贷痪,重寫了魔法方法__init__,但新的__init__方法里面沒有初始化鯊魚的x坐標(biāo)和y坐標(biāo)蹦误,因此調(diào)用move方法就會出錯劫拢。解決這個問題應(yīng)該在鯊魚類中重寫__init__方法的時候先調(diào)用基類Fish中的__init__方法。
- 調(diào)用未綁定的父類方法强胰。
- 使用super函數(shù)舱沧。
11.4.1 調(diào)用未綁定的父類方法
Fish.__init__(self)
注意:這個self并不是父類Fish的實例對象,而是子類Shark的實例對象哪廓,所以說這里未綁定的是指并不需要綁定父類的實例對象狗唉,使用子類的實例對象代替即可。
11.4.2 使用super函數(shù)
super()函數(shù)能夠幫我自動找到基類的方法涡真,而且還為我們傳入了self參數(shù)。
super函數(shù)的超級之處在于你不需要明確給出任何基類的名字肾筐,它會自動幫你找出所有基類以及對應(yīng)的方法哆料。由于你不用給出基類的名字,這就意味著如果需要改變類繼承關(guān)系吗铐,只要改變class語句里的父類即可东亦,而不必在大量代碼中去修改所有被繼承的方法。
11.5 多重繼承
語法:
class 類名(父類1唬渗,父類2典阵,父類3,…)
多重繼承很容易導(dǎo)致代碼混亂镊逝,所以當(dāng)不確定是否真的必須使用多重繼承的時候壮啊,請盡量避免使用它,因為有些時候會出現(xiàn)不可預(yù)見的BUG撑蒜。
11.6 組合
組合就是把類的實例化放在一個新類里面