Python 是一種易于學(xué)習(xí)又功能強(qiáng)大的編程語言。它提供了高效的高級數(shù)據(jù)結(jié)構(gòu),還能簡單有效地面向?qū)ο缶幊獭ython 優(yōu)雅的語法和動(dòng)態(tài)類型,以及解釋型語言的本質(zhì),使它成為多數(shù)平臺上寫腳本和快速開發(fā)應(yīng)用的理想語言。
Python 解釋器及豐富的標(biāo)準(zhǔn)庫,提供了適用于各個(gè)主要系統(tǒng)平臺的源碼或機(jī)器碼,這些可以到 Python 官網(wǎng):
?
https://www.python.org/
?
Python 解釋器易于擴(kuò)展,可以使用 C 或 C++(或者其他可以從 C 調(diào)用的語言)擴(kuò)展新的功能和數(shù)據(jù)類型。Python 也可用作可定制化軟件中的擴(kuò)展程序語言。
簡單來說,易用,需要深入理解和記憶的東西不需要很多,其次庫多,可以讓編寫者集中精神研究邏輯。其次就是免費(fèi)了,使用起來沒有什么成本。最后就是它真的很火,側(cè)面的好處就是別人遇到的問題早就被解決,生態(tài)良好。
我們經(jīng)常說,Python一行勝千語:
是因?yàn)镻ython 是一種解釋型語言,在程序開發(fā)階段可以為你節(jié)省大量時(shí)間,因?yàn)椴恍枰幾g和鏈接。解釋器可以交互式使用,這樣就可以方便地嘗試語言特性,寫一些一次性的程序,或者在自底向上的程序開發(fā)中測試功能。它也是一個(gè)順手的桌面計(jì)算器。
Python 程序的書寫是緊湊而易讀的。Python 代碼通常比同樣功能的 C,C++,Java 代碼要短很多,有如下幾個(gè)原因:
1.高級數(shù)據(jù)類型允許在一個(gè)表達(dá)式中表示復(fù)雜的操作;
2.代碼塊的劃分是按照縮進(jìn)而不是成對的花括號;
3.不需要預(yù)先定義變量或參數(shù)。
也就是說,樣板代碼變少了,一些獨(dú)特的語法糖也讓編寫的效率更高。
Python可以以很多的形式被運(yùn)行,一種是命令行終端,一種是腳本的樣子。
?
python -c command [arg] ...
?
其中 command 要換成想執(zhí)行的指令,就像命令行的?-c 選項(xiàng)。由于 Python 代碼中經(jīng)常會包含對終端來說比較特殊的字符,通常情況下都建議用英文單引號把 command 括起來。
有些 Python 模塊也可以作為腳本使用??梢赃@樣輸入:
?
python -m module [arg] ...
?
這會執(zhí)行 module 的源文件,就跟你在命令行把路徑寫全了一樣。
在運(yùn)行腳本的時(shí)候,有時(shí)可能也會需要在運(yùn)行后進(jìn)入交互模式。這種時(shí)候在文件參數(shù)前,加上選項(xiàng)?-i 就可以了。
如果可能的話,解釋器會讀取命令行參數(shù),轉(zhuǎn)化為字符串列表存入 sys 模塊中的 argv 變量中。執(zhí)行命令:
?
import sys
?
你可以導(dǎo)入這個(gè)模塊并訪問這個(gè)列表。這個(gè)列表最少也會有一個(gè)元素;如果沒有給定輸入?yún)?shù),sys.argv[0] 就是個(gè)空字符串。如果給定的腳本名是 '-' (表示標(biāo)準(zhǔn)輸入),sys.argv[0] 就是 '-'。使用 -c command 時(shí),sys.argv[0] 就會是 '-c'。如果使用選項(xiàng) -m module,sys.argv[0] 就是包含目錄的模塊全名。在 -c command 或 -m module 之后的選項(xiàng)不會被解釋器處理,而會直接留在 sys.argv 中給命令或模塊來處理。
有些東西不得不說,因?yàn)樗鼤r(shí)時(shí)刻刻存在,所以請?jiān)徫业膯隆?/p>
最后講一下編碼信息,你看到的程序其實(shí)和你看到的小說沒有什么區(qū)別,都是一堆0101010,但是為啥0101010就變成了你看到的字符,其實(shí)是因?yàn)榫幋a的緣故。
在編輯器的右下角,大概率都會看到這個(gè)
默認(rèn)情況下,Python 源碼文件以 UTF-8 編碼方式處理。在這種編碼方式中,世界上大多數(shù)語言的字符都可以同時(shí)用于字符串字面值、變量或函數(shù)名稱以及注釋中——盡管標(biāo)準(zhǔn)庫中只用常規(guī)的 ASCII 字符作為變量或函數(shù)名,而且任何可移植的代碼都應(yīng)該遵守此約定。要正確顯示這些字符,你的編輯器必須能識別 UTF-8 編碼,而且必須使用能支持打開的文件中所有字符的字體。
如果不使用默認(rèn)編碼,要聲明文件所使用的編碼,文件的 第一 行要寫成特殊的注釋。語法如下所示:
?
# -*- coding: encoding -*-
?
其中 encoding 可以是 Python 支持的任意一種 codecs。
比如,要聲明使用 Windows-1252 編碼,你的源碼文件要寫成:
?
# -*- coding: cp1252 -*-
?
關(guān)于 第一行 規(guī)則的一種例外情況是,源碼以 UNIX "shebang" 行 開頭。這種情況下,編碼聲明就要寫在文件的第二行。例如:
?
#!/usr/bin/env python3# -*- coding: cp1252 -*-
?
這可能會回答,為什么代碼一開始會有一行奇怪的東西。
本來是想直接給大家寫一些教程的,但是官網(wǎng)寫的真的太好啦!
?
https://docs.python.org/zh-cn/3.8/tutorial/introduction.html
?
大家直接去看。
字符串是可以被 索引 (下標(biāo)訪問)的,第一個(gè)字符索引是 0。單個(gè)字符并沒有特殊的類型,只是一個(gè)長度為一的字符串:
?
>>>>>> word = 'Python'>>> word[0] # character in position 0'P'>>> word[5] # character in position 5'n'
?
索引也可以用負(fù)數(shù),這種會從右邊開始數(shù):
?
>>>>>> word[-1] # last character'n'>>> word[-2] # second-last character'o'>>> word[-6]'P'
?
注意 -0 和 0 是一樣的,所以負(fù)數(shù)索引從 -1 開始。
除了索引,字符串還支持 切片。索引可以得到單個(gè)字符,而 切片 可以獲取子字符串:
?
>>>>>> word[0:2] # characters from position 0 (included) to 2 (excluded)'Py'>>> word[2:5] # characters from position 2 (included) to 5 (excluded)'tho'
?
注意切片的開始總是被包括在結(jié)果中,而結(jié)束不被包括。這使得 s[:i] + s[i:] 總是等于 s
?
>>>>>> word[:2] + word[2:]'Python'>>> word[:4] + word[4:]'Python'
?
切片的索引有默認(rèn)值;省略開始索引時(shí)默認(rèn)為0,省略結(jié)束索引時(shí)默認(rèn)為到字符串的結(jié)束:
?
>>>>>> word[:2] # character from the beginning to position 2 (excluded)'Py'>>> word[4:] # characters from position 4 (included) to the end'on'>>> word[-2:] # characters from the second-last (included) to the end'on'
?
您也可以這么理解切片:將索引視作指向字符 之間 ,第一個(gè)字符的左側(cè)標(biāo)為0,最后一個(gè)字符的右側(cè)標(biāo)為 n ,其中 n 是字符串長度。例如:
第一行數(shù)標(biāo)注了字符串 0...6 的索引的位置,第二行標(biāo)注了對應(yīng)的負(fù)的索引。那么從 i 到 j 的切片就包括了標(biāo)有 i 和 j 的位置之間的所有字符。
對于使用非負(fù)索引的切片,如果索引不越界,那么得到的切片長度就是起止索引之差。例如, word[1:3] 的長度為2。
試圖使用過大的索引會產(chǎn)生一個(gè)錯(cuò)誤:
?
>>>>>> word[42] # the word only has 6 charactersTraceback (most recent call last): File "", line 1, inIndexError: string index out of range
?
但是,切片中的越界索引會被自動(dòng)處理:
?
>>>>>> word[4:42]'on'>>> word[42:]''
?
Python 中的字符串不能被修改,它們是 immutable 的。因此,向字符串的某個(gè)索引位置賦值會產(chǎn)生一個(gè)錯(cuò)誤:
?
>>>>>> word[0] = 'J'Traceback (most recent call last): File "", line 1, inTypeError: 'str' object does not support item assignment>>> word[2:] = 'py'Traceback (most recent call last): File "", line 1, inTypeError: 'str' object does not support item assignment
?
如果需要一個(gè)不同的字符串,應(yīng)當(dāng)新建一個(gè):
?
>>>>>> 'J' + word[1:]'Jython'>>> word[:2] + 'py''Pypy'
?
記不?。縮tring就是個(gè)不可變的列表,完事兒了。
老師!等下!
?
什么是列表?。?/p>
Python 中可以通過組合一些值得到多種復(fù)合數(shù)據(jù)類型。其中最常用的列表 ,可以通過方括號括起、逗號分隔的一組值(元素)得到。一個(gè) 列表 可以包含不同類型的元素,但通常使用時(shí)各個(gè)元素類型相同:
粗糙點(diǎn)的話,這就介紹完了
但是為了完整性,這里要補(bǔ)一些,Python 編程語言中有四種集合數(shù)據(jù)類型:
列表(List)是一種有序和可更改的集合。允許重復(fù)的成員。
元組(Tuple)是一種有序且不可更改的集合。允許重復(fù)的成員。
集合(Set)是一個(gè)無序和無索引的集合。沒有重復(fù)的成員。
詞典(Dictionary)是一個(gè)無序,可變和有索引的集合。沒有重復(fù)的成員。
選擇集合類型時(shí),了解該類型的屬性很有用。為特定數(shù)據(jù)集選擇正確的類型可能意味著保留含義,并且可能意味著提高效率或安全性。
上面的都可以叫數(shù)據(jù)容器,也就是放東西的罐子。我們要對它動(dòng)手動(dòng)腳的,也就是要操作它。無外乎2種操作:取一些(看看里面有啥),改一些(比如調(diào)整順序,刪除)。
再總結(jié)一下,就是你做完操作,有沒有對這個(gè)原來的東西有副作用的。這樣的抽象模型是理解對數(shù)據(jù)操作的必由之路。
?
按說看懂了吧?
我假定你有其它語言的經(jīng)驗(yàn),這里就直接開始了
我們來想想,上面的代碼做了什么?初始化要使用的變量,開始操作變量,在一個(gè)合適的時(shí)機(jī)輸出結(jié)果。
第一行含有一個(gè)多重賦值: 變量 a 和 b 同時(shí)得到了新值 0 和 1. 最后一行又用了一次多重賦值, 這展示出了右手邊的表達(dá)式,在任何賦值發(fā)生之前就被求值了。右手邊的表達(dá)式是從左到右被求值的。
while 循環(huán)只要它的條件(這里指:a < 10)保持為真就會一直執(zhí)行。Python 和 C 一樣,任何非零整數(shù)都為真;零為假。這個(gè)條件也可以是字符串或是列表的值,事實(shí)上任何序列都可以;長度非零就為真,空序列就為假。在這個(gè)例子里,判斷條件是一個(gè)簡單的比較。
標(biāo)準(zhǔn)的比較操作符的寫法和 C 語言里是一樣:< (小于)、 > (大于)、 == (等于)、 <= (小于或等于)、 >= (大于或等于)以及 != (不等于)。
循環(huán)體是縮進(jìn)的 :縮進(jìn)是 Python 組織語句的方式。在交互式命令行里,你得給每個(gè)縮進(jìn)的行敲下 Tab 鍵或者(多個(gè))空格鍵。實(shí)際上用文本編輯器的話,你要準(zhǔn)備更復(fù)雜的輸入方式;所有像樣的文本編輯器都有自動(dòng)縮進(jìn)的設(shè)置。交互式命令行里,當(dāng)一個(gè)組合的語句輸入時(shí), 需要在最后敲一個(gè)空白行表示完成(因?yàn)檎Z法分析器猜不出來你什么時(shí)候打的是最后一行)。注意,在同一塊語句中的每一行,都要縮進(jìn)相同的長度。
print() 函數(shù)將所有傳進(jìn)來的參數(shù)值打印出來. 它和直接輸入你要顯示的表達(dá)式(比如我們之前在計(jì)算器的例子里做的)不一樣, print() 能處理多個(gè)參數(shù),包括浮點(diǎn)數(shù),字符串。字符串會打印不帶引號的內(nèi)容, 并且在參數(shù)項(xiàng)之間會插入一個(gè)空格, 這樣你就可以很好的把東西格式化。
縮進(jìn)這個(gè)事情,其實(shí)Python的創(chuàng)始人說,沒有那么夸張,只是必要的縮進(jìn)會對閱讀代碼有益,現(xiàn)在看到是比較糟糕的設(shè)計(jì),最好還是使用括號來匹配。
end參數(shù)可以取消輸出
再看看分支結(jié)構(gòu),分支結(jié)構(gòu)是賦予計(jì)算機(jī)判斷能力的本源動(dòng)力
可以有零個(gè)或多個(gè) elif 部分,以及一個(gè)可選的 else 部分。關(guān)鍵字 'elif' 是 'else if' 的縮寫,適合用于避免過多的縮進(jìn)。一個(gè) if ... elif ... elif ... 序列可以看作是其他語言中的 switch 或 case 語句的替代。再最新的3.10版本已經(jīng)有了switch語句,但是太新的特性了,不建議使用。
Python 中的 for 語句與你在 C 或 Pascal 中所用到的有所不同。Python 中的 for 語句并不總是對算術(shù)遞增的數(shù)值進(jìn)行迭代(如同 Pascal),或是給予用戶定義迭代步驟和暫停條件的能力(如同 C),而是對任意序列進(jìn)行迭代(例如列表或字符串),條目的迭代順序與它們在序列中出現(xiàn)的順序一致。?
?
words = ['cat', 'window', 'defenestrate']for w in words: print(w, len(w))
?
在遍歷同一個(gè)集合時(shí)修改該集合的代碼可能很難獲得正確的結(jié)果。通常,更直接的做法是循環(huán)遍歷該集合的副本或創(chuàng)建新集合:
?
for user, status in users.copy().items(): if status == 'inactive': del users[user] # Strategy: Create a new collectionactive_users = {}for user, status in users.items(): if status == 'active': active_users[user] = status
?
for 語句用于對序列(例如字符串、元組或列表)或其他可迭代對象中的元素進(jìn)行迭代:
?
for_stmt ::= "for" target_list "in" expression_list ":" suite ["else" ":" suite]
?
表達(dá)式列表會被求值一次;它應(yīng)該產(chǎn)生一個(gè)可迭代對象。系統(tǒng)將為 expression_list 的結(jié)果創(chuàng)建一個(gè)迭代器,然后將為迭代器所提供的每一項(xiàng)執(zhí)行一次子句體,具體次序與迭代器的返回順序一致。每一項(xiàng)會按標(biāo)準(zhǔn)賦值規(guī)則 (參見 賦值語句) 被依次賦值給目標(biāo)列表,然后子句體將被執(zhí)行。當(dāng)所有項(xiàng)被耗盡時(shí) (這會在序列為空或迭代器引發(fā) StopIteration 異常時(shí)立刻發(fā)生),else 子句的子句體如果存在將會被執(zhí)行,并終止循環(huán)。
第一個(gè)子句體中的 break 語句在執(zhí)行時(shí)將終止循環(huán)且不執(zhí)行 else 子句體。第一個(gè)子句體中的 continue 語句在執(zhí)行時(shí)將跳過子句體中的剩余部分并轉(zhuǎn)往下一項(xiàng)繼續(xù)執(zhí)行,或者在沒有下一項(xiàng)時(shí)轉(zhuǎn)往 else 子句執(zhí)行。
for 循環(huán)會對目標(biāo)列表中的變量進(jìn)行賦值。這將覆蓋之前對這些變量的所有賦值,包括在 for 循環(huán)體中的賦值:
?
for i in range(10): print(i) i = 5
?
目標(biāo)列表中的名稱在循環(huán)結(jié)束時(shí)不會被刪除,但如果序列為空,則它們根本不會被循環(huán)所賦值。提示:內(nèi)置函數(shù) range() 會返回一個(gè)可迭代的整數(shù)序列,適用于模擬 Pascal 中的:
?
for i := a to b do
?
這種效果;例如 list(range(3)) 會返回列表 [0, 1, 2]。
當(dāng)序列在循環(huán)中被修改時(shí)會有一個(gè)微妙的問題(這只可能發(fā)生于可變序列例如列表中)。會有一個(gè)內(nèi)部計(jì)數(shù)器被用來跟蹤下一個(gè)要使用的項(xiàng),每次迭代都會使計(jì)數(shù)器遞增。當(dāng)計(jì)數(shù)器值達(dá)到序列長度時(shí)循環(huán)就會終止。這意味著如果語句體從序列中刪除了當(dāng)前(或之前)的一項(xiàng),下一項(xiàng)就會被跳過(因?yàn)槠錁?biāo)號將變成已被處理的當(dāng)前項(xiàng)的標(biāo)號)。類似地,如果語句體在序列當(dāng)前項(xiàng)的前面插入一個(gè)新項(xiàng),當(dāng)前項(xiàng)會在循環(huán)的下一輪中再次被處理。這會導(dǎo)致麻煩的程序錯(cuò)誤,避免此問題的辦法是對整個(gè)序列使用切片來創(chuàng)建一個(gè)臨時(shí)副本:
?
for x in a[:]: if x < 0: a.remove(x)
?
一般重復(fù)語句主要有兩種類型的循環(huán):
1)重復(fù)一定次數(shù)的循環(huán),這個(gè)稱謂計(jì)數(shù)循環(huán)。
比如打印1到99之間所有的整數(shù),就是重復(fù)99次執(zhí)行print( )指令。
2)重復(fù)直至發(fā)生某種情況時(shí)結(jié)束的循環(huán),成為條件循環(huán)。也就是說只有條件為True,循環(huán)才會一直持續(xù)下去。
比如猜數(shù)字,如果沒猜中就繼續(xù)猜,如果猜中了就退出。
循環(huán)的知識太多了,其實(shí)就是簡簡單單的重復(fù),但是最難的就是什么時(shí)候停下來再做別的事情。
在C語言里面的循環(huán)大多數(shù)是小于一個(gè)什么數(shù)字,也就是變相的輸出了一些算數(shù)級數(shù),在Python里面有著更加優(yōu)雅的寫法。
?
for i in range(5): print(i)
?
給定的終止數(shù)值并不在要生成的序列里;range(10) 會生成10個(gè)值,并且是以合法的索引生成一個(gè)長度為10的序列。range也可以以另一個(gè)數(shù)字開頭,或者以指定的幅度增加(甚至是負(fù)數(shù);有時(shí)這也被叫做 '步進(jìn)')
但是更加的常見一種用法是:
?
a = ['Mary', 'had', 'a', 'little', 'lamb']for i in range(len(a)): print(i, a[i])
?
我相信你一定會看到這個(gè)寫法。
當(dāng)然Python里面還有別的寫法:
函數(shù)返回一個(gè)枚舉對象。iterable 必須是一個(gè)序列,或 iterator,或其他支持迭代的對象。enumerate() 返回的迭代器的 __next__() 方法返回一個(gè)元組,里面包含一個(gè)計(jì)數(shù)值(從 start 開始,默認(rèn)為 0)和通過迭代 iterable 獲得的值。
當(dāng)然我們這樣也可以實(shí)現(xiàn),但是有現(xiàn)成的干嘛不用
range()?所返回的對象在許多方面表現(xiàn)得像一個(gè)列表,但實(shí)際上卻并不是。此對象會在你迭代它時(shí)基于所希望的序列返回連續(xù)的項(xiàng),但它沒有真正生成列表,這樣就能節(jié)省空間。
我們稱這樣對象為?iterable,也就是說,適合作為這樣的目標(biāo)對象:函數(shù)和結(jié)構(gòu)期望從中獲取連續(xù)的項(xiàng)直到所提供的項(xiàng)全部耗盡。我們已經(jīng)看到?for?語句就是這樣一種結(jié)構(gòu)。
關(guān)于迭代器就不說了,它就是一種協(xié)議而已。
評論
查看更多