1. Python 基礎語法
1.1. 注釋
??在 Python 中主要的使用的注釋方式是 # 號,# 號后面緊跟注釋內(nèi)容,當然在某些情況下三個單引號/雙引號也是可以的,比如在函數(shù)中可以作為函數(shù)的說明。
num = int(input('Please input a number: ')) # 輸入一個數(shù)字
if num >= 1000: # 條件判斷
if num >= 10000: # 大于 10000
print('5') # 打印 5 位
else: ''' 否則 '''
print('4') ''' 打印 4'''
else:
if num >= 100:
print('3')
elif num >= 10:
print('2')
else:
print('1')
1.2. 縮進
??C 語言用花括號來表示層級關系,不夠簡潔,而 Python 使用的是縮進的方式表示層級關系,一般約定 4 個空格 縮進為一個層級,層次明確清晰,代碼格式規(guī)范統(tǒng)一,可讀性高。
1.3. 續(xù)行
??當一行代碼超過了一屏能顯示的最大長度后,為了直觀,我們會另起一行接著寫,在 Python 中在行尾使用 \ 標識續(xù)行,但如果在表達式或者某一段代碼中使用了括號,那么 Python 認為括號內(nèi)是一個整體,內(nèi)部跨行不需要使用 \。
1.4. 標識符
??很多時候,我們寫代碼的過程中會對我們需要的數(shù)據(jù)進行存儲并命名,方便后續(xù)使用,這個命名被稱為標識符,針對標識符 Python 有如下要求:
- 一個名字,用來指代一個值
- 只能是字母、數(shù)字下劃線的組合
- 只能以字母或者下劃線開頭
- 不能是 Python 的關鍵字,例如 def、class 就不能作為標識符
- Python 是大小寫敏感的
??為了避免誤解,造成不必要的麻煩,在我們寫代碼的過程中還應遵循下列約定:
- 不允許使用中文
- 不允許使用歧義單詞,例如 class_
- 在 Python 中不要隨便使用下劃線開頭的標識符
1.5. 轉義序列
??python 中內(nèi)置了很多特殊的符號,比如換行、制表符等,部分含義如下:
-
\\:單個\表示轉義,\\就指代\這個符號。 -
\t:制表符,一般用來進行輸出格式調(diào)整,比如對齊等 -
\r:回車符 -
\n: 換行符
1.6. 數(shù)字
??在 Python 中數(shù)字主要分為三種類型:整型,浮點數(shù),復數(shù)。
-
整型:在 Python3 中,不區(qū)分 long 和 int,所有整型均為 int 類型,當然還包括了不同進制,比如 2 進制,8 進制,16 進制等,都為 int 類型。需要注意的是 Python 中的bool 型屬于整型的子類,所以 bool 的兩個值,用整型可以表示為,0:False; 非 0:True。 -
浮點數(shù):即帶小數(shù)點的 float 型 -
復數(shù):用于科學計算,比如 1+2j 等
1.7. 字符串
??在 Python 中,成對使用單引號 ' 或雙引號 " 括起來表示引用字符的序列,成對使用三個單引號 ''' 或雙引號 """,則可以跨行,并且在其中自由的使用單雙引號。除此之外還可以在字符串前加一定的符號來確切的表示字符串。
-
r: 字符串前加 r 或者 R,表示該字符串不做任何處理,所見即所得 -
f: 3.6 版本開始新增的前綴,表示格式化字符串,例如變量引用
str1 = r'hello\nworld' # 由于使用了 r 前綴,所以并不會把 \n 解釋為換行
str2 = f'nihao {str1}' # 類似于 'nihao {}'.format(str1)
print(str1)
hello\nworld
print(str2)
nihao hello\nworld
1.8. 其他
??在 Python 中還有一些地方和其他語言有很大區(qū)別,比如:
- 常量:本身指代一旦賦值就不能被改變的標識符,但是 Python 中無法定義常量,換句話說就是,Python 中,只要你看得到的東西,都是可以進行修改的。
- 字面常量:一個單獨的量,看字面意思就知其含義,比如 12、"abc"、'2341356514.03e-9'
- 變量:賦值后,可以改變值的標識符。
注意:在 Python 中是不需要提前申明變量的類型的,所以變量的賦值即定義
# 定義了一個 total 變量,它的值是 2500,類型是整數(shù)型。 賦值即定義
total = 2500
2. Python 運算符
??在 Python 中,運算符是比較重要的知識了,因為很多地方都需要知道多個數(shù)據(jù)的大小關系、邏輯關系,當然賦值也是需要用到運算符的,根據(jù)類型的不同,主要分為 賦值運算符、算數(shù)運算符、關系運算符、邏輯運算符 以及 位運算符。
2.1. 賦值運算符
??我們?nèi)粘J褂玫?= 號 就屬于賦值運算符的一種,在 Python 還有如下算數(shù)運算符:
-
=:賦值,例如:x=3,y='abc' -
+=:自加,例如:x+=2,則表示 x=x+2 -
-=:自減,例如:x-=2,表示 x=x-2 -
*=:自乘,例如:x=2, 表示 x=x2 -
/=:自除,例如:x/=2,表示 x=x/2 -
%=:自取余,例如:x%=2,表示 x=x%2。 x 對 2 取余數(shù),假如 x=6,那么取余為 0
??當把數(shù)字賦值給一個變量的時候不用加引號,而將字符串賦值給變量的時候需要加引號,否則 python 會認為你賦值的是另一個變量,而非字符串。
2.2. 算數(shù)運算符
??數(shù)學計算中的 +,-,* 等都屬于算數(shù)運算符的一種,其他的運算符如下:
-
+:加,用來計算數(shù)字,如果字符串、列表等相加,等于是把兩個對象拼接到一起 -
-:減,同數(shù)學減 -
*:乘,同數(shù)學乘 -
/:自然除,結果是浮點數(shù),4 / 3答案是 1.33333。注:2.x中/和//都是整除 -
//:整除,運算結果只取整數(shù),如果用4 // 3答案是 1 -
%:表示取余數(shù),10 % 2余 0,10%3 余 1 -
**:表示乘方2**3表示 2 的 3 次方
2.3. 關系運算符(比較運算符)
??關系運算符顧名思義就是判斷關系的,比如大于,小于,等等,需要注意的是返回值為布爾值:即 True 或者 False。更多的符號有:
-
>:大于,例如 1>2,值是 False -
<:小于,例如 1<2,值是 True -
>=:大于等于,例如 1>=2,值是 False -
<=: 小于等于,例如 1<=2,值是 True -
==:是否等于,例如 1==2,值是 False -
!=:不等于,例如 1!=2,值是 True
2.4. 邏輯運算符
??邏輯運算符主要包含了三個:and,or,not
-
and:邏輯與,只要有 1 個是 False 那么值就是 False,1==2 and 1<2的值是 False,1!=2 and 1<2的值是 True -
or:邏輯或,只要有一個是 True 那么值就是 True,1=2 and 1<2的值是 True -
not:邏輯非,取反not 1<2的值是 False
邏輯運算符又被稱為短路運算符:
- and 如果第一個表達式為 False,后面就沒必要計算了,這個邏輯表達式一定為 False
- or 如果第一個表達式為 True,后面就沒必要計算了,這個邏輯表達式一定為 True
2.5. 位運算符
??故名思議,位運算符主要是針對位進行的計算的,它比加減運算略快,通常也比乘除法運算要快很多。說到位就不得不提補碼了,因為計算機存儲負數(shù)時使用的都是補碼。
2.5.1. 原碼、反碼、補碼、負數(shù)表示法
??早期數(shù)字電路的CPU中的運算器實現(xiàn)了加法器,但是沒有減法器,減法要轉換成加法,如何理解呢?例如 5-1,在計算機中進行計算的時候?qū)嶋H上用的是 5+(-1), 而負數(shù)在內(nèi)存中并不會直接寫個 -0b1, 負數(shù)在計算機中使用的是補碼進行存儲和運算的,計算機中有關數(shù)字的都有什么瑪?什么是補碼?
- 原碼:即人類可讀的二進制位(0b101,0b1)
- 反碼:正數(shù)的反碼與原碼相同;負數(shù)的反碼符號位不變其余按位取反
- 補碼:正數(shù)的補碼與原碼相同;負數(shù)的補碼符號位不變其余按位取反后 + 1
??需要注意的是:負數(shù)在計算機中使用補碼進行存儲,比如
-1在計算機存儲的是1111 1111,負數(shù)補碼的補碼就表示負數(shù)本身。正數(shù)的原碼反碼補碼都是相同的,計算機存儲內(nèi)存中的數(shù)字都為二進制位,當我們想要查看具體代表的值時,計算機會轉換為人類可讀的原碼進行顯示,即:如果最高的符號位是 0,那么認為它是正數(shù),不進行去補,而最高的符號位如果是 1,那么它會認為它是負數(shù),會按照負數(shù)的取補的規(guī)則進行計算后展示。
例題:計算機計算 5 - 1 的過程
# 計算機中計算的是
5 + -1
# 推導步驟:
0000 0101 # 5 的原碼
1000 0001 # -1 的原碼
1111 1110 # -1 的反碼
1111 1111 # -1 的補碼
0000 0101 # 5 是正數(shù),補碼與原碼相同
1111 1111 # -1 的補碼
10000 0100 # 溢出位舍去
0000 0100 # 5-1 的結果為 4
例題:計算~12
# ~12 表示取反
# 先將初始數(shù)轉換為二進制,再對補碼去取反
0000 1100 # 12 的補碼與原碼相同
1111 0011 # 12 按位取反,得到一個補碼
1000 1100 # 要轉換成原碼便于人類閱讀,補碼再次取反,得到反碼
1000 1101 # +1 得到原碼
轉換為 10 進制就是 -13 了
2.5.2. 位運算符
??針對位的運算符主要有:& | ~ ^ << >>.
-
&:按位與,相當于按位相乘(1101 & 0001, 按位與結果是 0001 ) -
|:按位或,相當于按位相加,不進位(1101 | 0001,按位或結果是 1101 ) -
^:按位異或 -
~:取反 -
<<:左移(位) -
>>:右移(位),例如 32 >> 3 等于 32 // 8 , 結果是 4
位運算符,日常使用的不多,但是如果你想做一個高級程序員,那么位運算是你必備的技能哦
2.6. 成員、身份運算符
-
in/not in成員測試,測試一個元素是否在一個序列中 -
is/is not統(tǒng)一性的測試
2.7. 運算符優(yōu)先級(由高到低)
| 運算符 | 描述 | |
|---|---|---|
~ |
按位取反 | |
+ -
|
一元加號和減號(方法名為 +@ 和 -@),正數(shù)、負數(shù) | |
** |
冪運算 | |
* / % //
|
乘,除,取模和取整除 | |
+ -
|
加法減法 | |
>> <<
|
右移,左移位運算符 | |
& |
按位與 | |
^ |
按位異或 | |
| ` | ` | 按位或 |
<= <> >=
|
比較運算符 | |
<> == !=
|
等于運算符 | |
= %= /= //= -= += *= **=
|
賦值運算符 | |
is is not
|
身份運算符 | |
in not in
|
成員運算符 | |
not and or
|
邏輯運算符 |
小結:
-
算數(shù)運算符>位運算符>身份運算符>成員運算符>邏輯運算符 -
單目運算符>雙目運算符(一元運算符>二元運算符) - 記不住優(yōu)先級的話,可以用括號,括號內(nèi)的優(yōu)先級更高
- 長表達式,多用括號,易懂易讀。
注意:在 Python 中,賦值即定義,如果一個變量已經(jīng)定義,賦值相當于重新定義
3. Python 內(nèi)存管理
??計算機的內(nèi)存大多是線性編址的(1001,1002,1003 門牌號,挨著排列的),現(xiàn)在有一個變量 var1 需要 1001~1007 空間,var2 需要 1008~1012 空間,如下圖

??過了一段時間以后,var1 中的 1002,和 1005 不用了,var2 的 1010 也不用了,內(nèi)存就變成了如下的情況:

??這時又來了一個 var3 需要申請 3 個連續(xù)的空間,在當前情況下就沒辦法進行分配了

??這種情況就是我們常說的
內(nèi)存空洞了,也叫內(nèi)存碎片化,如果沒辦法進行碎片整理,那么這些分散的內(nèi)存空間將沒有辦法被重新使用
3.1. Python 的內(nèi)存特性
- 變量無需事先聲明,也不需要指定類型,這是動態(tài)語言的特性
- Python 使用
引用計數(shù)記錄所有對象的引用數(shù)。 - 當對象的引用數(shù)變?yōu)?0,它就可以被垃圾回收 GC(Garbage Collection)
- 當對變量進行賦值時,同時會增加該對象的引用計數(shù)
- 函數(shù)或代碼塊運行完畢,變量會消亡,那么引用計數(shù)會減少
3.2. Python 的 GC 管理
??Python 在對內(nèi)存進行管理時會像 Java 那樣對內(nèi)存進行分類,Java 中將內(nèi)存分為了老生代,新生代,持久化代,而 Python 中則分成了 0,1,2 三代,其中 0 代可以理解為臨時存儲,1 代為短期存儲,2 代為長期存儲,當應用申請內(nèi)存時,會根據(jù)內(nèi)存情況先分配 0 帶給程序使用,然后定期檢查各個區(qū)的使用情況,如果某個程序在 0 區(qū)待的夠久,那么在 Python 啟動 GC 的時候,就會把它從 0 區(qū)移動到 1 區(qū),同理在 1 區(qū)時間夠久的,移動到 2 區(qū)。當然在啟動 GC 的時候還會檢查引用計數(shù)為 0 的對象,然后清理掉。
??需要注意的是,Python 啟動 GC 的同時,不能進行其它的任務。頻繁的垃圾回收將大大降低 Python 的工作效率。如果內(nèi)存中的對象不多,就沒有必要總啟動垃圾回收。所以,Python 只會在特定條件下,自動啟動垃圾回收。當 Python 運行時,會記錄其中分配對象(object allocation) 和取消分配對象(object deallocation) 的次數(shù)。當兩者的差值高于某個閾值時,垃圾回收才會啟動。

所以:
- Python 編程中一般無需關心變量的存亡,一般也不用關心內(nèi)存的管理,由 Python 的 GC 統(tǒng)一進行垃圾回收
- 當有關 Python 性能問題的時候,就需要考慮變量引用的問題,盡量不要釋放內(nèi)存,交由 Python GC 來操作,除非你更懂它。
# 查看引用計數(shù)
# 由于 1,2,15 等這種常數(shù),同時被 Python 語言解釋器本身等引用,所以直接打印計數(shù)器它的引用計數(shù)并不會是 1。
>>> import sys
>>> x = []
>>> print(sys.getrefcount(x)) # 函數(shù)在執(zhí)行時會進行參數(shù)傳遞操作,會使引用計數(shù) + 1
2
>>> print(sys.getrefcount([]))
1
>>>
4. 程序控制
??Python 的程序控制主要分為順序,分支,循環(huán),這也和大多數(shù)語言是相同的。
-
順序結構:按照先后順序一條一條執(zhí)行,比如:先起床,再刷牙,再吃飯 -
分支結構:根據(jù)不同的情況判斷,條件滿足后執(zhí)行相應的操作,比如你去買個西紅柿,如果西紅柿新鮮就買兩個,如果不新鮮就只買一個 -
循環(huán)結構:條件滿足就反復執(zhí)行,不滿足就不執(zhí)行或者不再執(zhí)行(循環(huán)完畢),比如吃飯,在吃飽這個條件滿足之前一口一口不停地吃,直到吃飽為止
4.1. 分支結構
??計算機之所以能做很多自動化的任務,因為它可以自己做條件判斷。在 Python 中主要通過 if 以及 else 的搭配來完成條件判斷的工作。條件判斷主要有三種基本用法:單分支、多分支、分支嵌套。
4.1.1. 單分支
??顧名思義即如果怎么樣,就怎么樣。(if)
if expression:
block
注意:
python 使用縮進作為其語句分組的方法,請使用 4 個空格
expression 表示條件表達式(比如:a>b)
statement 表示要執(zhí)行的代碼
表達式:是將不同的數(shù)據(jù)(包括變量、函數(shù))用運算符號按一定規(guī)則連接起來的一種式子。
4.1.2. 多分支
??多分支有分為兩種情況:
- 如果滿足條件,就怎么樣;否則,就怎么樣。(if、else)
- 如果滿足條件 1,就怎么樣;如果滿足條件 2,就怎么樣;...;否則,就怎么樣(if、elif、else)
if expression:
block
else:
block
# if、elif、else 都屬于同級
if expression:
block
elif expression:
block
else:
block
4.1.3. 分支嵌套
??分支嵌套,就是將多個兩個或多個 if 判斷進行層級嵌套,完成更精確的判斷。
if expression:
block # 非必須,看情況
if expression:
block
else: # 非必須,看情況
block # 非必須,看情況
else:
block
4.1.4. 小結
- 條件的寫法非常多,可以寫一個表達式或者多個表達式都可以,表達式的值為 0,就表示 False,非 0,則表示 True。
- if 就是判斷,主要就是對表達式的邏輯值進行判斷
- 邏輯值(bool)包含了兩個值:
-
True:表示非空的量(比如:string、tuple、list、set、dictionary),所有非零數(shù)。 -
False:表示 0,None,空的量(空字符串,空字典,空列表,空即可,空元祖) 等。這些對象與False等價
-
4.2. 循環(huán)
??為了讓計算機能反復執(zhí)行某一操作,我們需要循環(huán)語句來完成。Python 中的循環(huán)主要有兩種:for 循環(huán)和 while 循環(huán)。
4.3. for 循環(huán)
??基本所有語言都有 for 關鍵字,它的曝光率遠遠超過其它關鍵字,但每個語言有它自己的格式,在 Python 中它的格式為
for element in iterable:
block
element 在循環(huán)時表示元素的變量(自行指定)
iterable:這里表示一個可迭代對象,比如字符串,列表
block 表示要執(zhí)行的代碼段
??在很多情況下,我們需要循環(huán)一定次數(shù),我們一般使用 range 函數(shù)來構建可迭代對象。
# range 用法說明:
range(stop) --> range object
range(start, stop [, step]) --> range object
??range 函數(shù),接受一個變量,做為停止位,從 0 到 stop 開始依次循環(huán),但是不包含停止位本身,所以我們稱它為前包后不包
4.4. while 循環(huán)
語法:
while condition:
block
??當條件滿足即 condition 為 True,進入循環(huán)體,執(zhí)行 block,每執(zhí)行一次 block 都會檢查一遍 condition,當 condition 為 False 時跳出循環(huán)體
4.5. 循環(huán) continue 語句
??循環(huán) continue 語句的作用是中斷當前循環(huán)的當次執(zhí)行,繼續(xù)下一次循環(huán)
舉例:計算10以內(nèi)的偶數(shù)(for循環(huán))
for i in range(10):
if not i % 2: # 與 2 相除沒有余數(shù),則為偶數(shù)
print(i)
??還有其它的實現(xiàn)嗎?
舉例:計算10以內(nèi)的偶數(shù)(for循環(huán))
for i in range(0,10,2): # 減少迭代次數(shù)
print(i)
for i in range(0,10): # 使用位與
if i & 1: # 奇數(shù)轉換為二進制數(shù)后,最低位一定是 1
continue
print(i)
4.6. 循環(huán) break 語句
??循環(huán) break 語句的作用是終止當前循環(huán)
舉例:計算1000以內(nèi)的正整數(shù)能被7整除的前20個數(shù)(for循環(huán))
count = 1
for i in range(7, 1000, 7):
print(i)
if count == 20:
break
count += 1
循環(huán) continue、break 語句小結:
- continue 和 break 是循環(huán)的控制語句,只影響當前循環(huán),包括 while、for 循環(huán)
- 如果循環(huán)嵌套,continue 和 break 也只影響語句所在的那一層循環(huán)
- continue 和 break 不是跳出語句塊,所以
if cond: break不是跳出 if,而是終止 if 外的 break 所在的循環(huán)
4.7. 循環(huán) else 子句
語法:
while condition:
block
else:
block
for element in iterable:
block
else:
block
- 如果循環(huán)正常的執(zhí)行結束,就執(zhí)行 else 子句,即使循環(huán)都沒有進去
- 如果使用 break 終止,else 子句不會執(zhí)行