python高級(1)—— 基礎回顧1

Python基礎回顧

 

認識變量  

在學習了以前的Python零基礎入門系列【洗禮靈魂,修煉Python】(說明一下,這個系列如今回過來再來看這個名字確實好土啊,而後有些知識點感受還不太精準,後期看若是有時間再調整下,名字的話就這樣了,不想改了,要改的話起碼得改大半天),相信你已經對Python有了一個大概的瞭解了。本系列是Python高級,因此先簡單回顧一下html

 

變量及變量的做用

 

變量,顧名思義,變量,那固然是會變的量了。固然這麼說感受有點枯燥,好,先看個例子:python

計算某人天天的總支出,已知,早餐6塊,中餐15塊,晚餐15塊,交通費6塊,若是天氣炎熱,飲料費6塊linux

 

好的以上的價格按照生活常識的話都是不固定的,因此咱們只是算個大概,打開Python自帶的IDLE交互式工具(固然你也能夠打開pycharm之類的編輯器):git

 

 

這樣,就計算出告終果了。程序員

那麼問題來了,一個正常的人,天天遇到的狀況也確定有不少種,好比今天早上這人起得晚,沒吃早飯(早餐則成了0),而後由於趕時間去公司打了個車(交通費變得更多了),那麼這天天的支出就又要從新算一下了,又要重複上面的操做一次,這樣算多了則會帶來一系列的問題,好比中間有個式子算錯了,那麼全盤皆錯,並且還不方便後期進行修改和刪除一些數據,那這個問題有沒有個好點方法來節省下咱們的運算量呢?編程

答案固然是有的,想一下,咱們在學生時代,學解方程的時候是怎麼作的?設未知數爲X對吧?而後根據條件寫出一個式子,而後就能夠計算這個未知數真實的值了對吧?而在編程語言裏,也是有這個設未知數概念的,不過稍微有些不一樣,咱們不會永遠都只用X,會用到不少,而這個設定的未知數則叫變量windows

 

在上面這個晚起的情景裏,咱們先設定breakfast = 0(即晚起沒吃到早餐),打車費爲trans = 20,而後依次操做依次設定變量,最後咱們再加起來:數組

 

 

結果計算出來了對吧?相信有朋友看到這裏還感受不到變量的強大,那麼假如這我的沒有晚起,而後一切正常的,咱們再用變量計算一次:編程語言

 

 

有朋友會以爲有點奇怪對吧?怎麼沒有把午飯,晚餐,飲料之類再加上呢?並且還算出來了,結果仍是對的?編輯器

這就是變量的做用了,它能夠臨時存儲值,而且這裏按照正常狀況,我只須要改下breakfast 和trans 值,其餘都不變就好了。因此到如今發現變量的做用了吧?若是你還不太懂,不急,後面開始通篇都會大量的使用變量,到時候天然會意會的。

 

 

上面的這種 breakfast(中文意思即爲早餐)=  6 (這裏的符號「=」是賦值符號,不等同於數學裏的等於符號)究竟是什麼意思呢,就是指把6這個值賦值給breakfast這個變量上,圖解:

 

 

咱們能夠直接調用變量訪問它的值,也能夠用print打印它的值:

 

 

 

 

固然你也能夠用del語句來刪除你定義的變量:

 

 

 

當用del語句刪除以後,再次調用這個變量時就會報錯提示該變量名未定義

 

 

那麼在全部的編程語言裏,把這個breakfast =6這個操做都稱爲把6賦值給breakfast,這個操做其實在全部的編程語言裏都是兩個步驟:

  1. 聲明變量

  2. 定義變量

 

不過在Python中,您可能要注意兩點:

 

  • Python定義變量的同時則會把聲明變量和定義變量兩個步驟同時進行

  • Python的定義變量時,並非簡單意義上的賦值,而是引用變量

 

 

什麼是變量引用

 

先看個例子:

 

 

 

這幾行的意思是,a=4,那麼此時a的值即爲4,接下來我又讓a=6,此時a的值即爲6,但b仍是4,並無跟着a一塊兒改變值,b從新等於8,a也不會跟着b改變,圖解:

 

 注:當Python的某個對象的引用計數降爲0時,說明沒有任何引用指向該對象,這個對象不久會被回收,回收這個對象的機制就是內存管理機制

 

這就是變量引用的特性,那麼經過以上,相信您應該理解什麼是變量了,變量的做用天然就是臨時存儲數據了 

 

然而這變量定義是不是隨便咱們定義的呢?好像看起來很隨意對吧?其實仍是有個規範的,沒有規矩不成方圓

 

變量定義的規範

 

  • 變量名能夠是字母,數字,下劃線,但變量不能以數字開頭

  • 嚴格區分大小寫

  • 變量的名字儘可能取專業的名字,作到顧名思義

 

 

其實定義變量還有個不成文的規定,不能使用中文和拼音命名,雖然也能夠用中文或者拼音來命名,可是請您千萬不要這麼作,這是很low的表現

 

 

上面的變量規範若是您不相信,那麼你能夠試試:

 

 

 

 

這個紅色不是我把它標紅的,它本身紅的,出現這個相信您已經知道這是報錯的意思,那麼定義變量時真的不能夠這麼操做的,你就記住定義變量只能是字母數字下劃線,並且字母不能做爲開頭就好了

 

 

 

 

數字和運算

 

前面咱們用breakfast = 6定義變量並賦值,那麼你有沒有想,這裏的6有沒有什麼特殊的含義呢?固然是有的

 

數字/常量

 

前面的變量定義breakfast = 6,這個6就是數字,它還有另外一個名字——常量

 

那麼這個常量有什麼可說的呢?首先你們都知道這個6是整數對吧,那麼確定還有帶小數的或者分數,負數,複數之類的。而在Python中,這些數都有什麼名字呢?

 

數據類型:

 

  • 整形數(int): 即整數,如1,2,-1,-2

  • 浮點型(float): 即帶小數的數,如1.2,3.1415,-1.2,-3.1415

  • 布爾型(bool): 即1(True)和0(False)。(這個在流程控制會詳細講到,這裏暫且不提)

  • 複數型:即帶「j」的數字就是複數型(其實複數用得很少,做爲了解便可)

   

 

其實數據類型還有長整型(long)和定點型(double),長整型是Python2裏特有的概念,實質上它仍是整數,由於Python2當時可表示的數值位數有限,因此有長整型的概念,而如今Python3裏都通稱爲整型了。

 

定點型其實也是帶小數的數,實質上和浮點型沒多大區別,而且幾乎用不到的。

 

那麼,咱們知道這些數據類型以後,怎麼查看一個數或者一個變量的數據類型呢?

Python給咱們分配了兩元大將——type函數和instance函數

 

type函數:

 

 

因此咱們能夠得出結論:type函數會返回變量的數據類型

 

instance函數:

 

 

 

 

報錯提示,指這個isinstance須要傳入兩個參數,而咱們只傳入了一個參數,因此報錯,那麼咱們這裏只有一個參數啊,爲了查看變量類型的,查閱幫助文檔得:

 

 

那麼根據這個幫助文檔,isinstance後面傳入的參數是數據類型(int,float等)

 

好咱們再試試看:

 

 

 

 

那麼這裏咱們又能夠得出結論:isinstance它會返回一個bool類型,若是是對的,那麼就是true,不然就是false。

 

 

簡單運算(運算操做符)

 

1).算術操做符:

有了以上的知識,相信各位已經摩拳擦掌準備體驗一下了,好的,咱們隨便測試幾個看看:

 

 

 

以上這些就是簡答的加(+)減(-)乘(*)除(/)了

 

 

2).比較操做符 (> 大於,>= 大於等於,<  小於,<= 小於等於,== 等於,!= 不等於)

3).邏輯操做符 (in 屬於,or 或,and 且,not in 不屬於,is  等同於)

 

4).冪運算/開根運算 (**,sqrt)

 

 

上面這個就是冪運算了。那麼開根運算是什麼呢?

這裏就須要導入一個math模塊裏的sqrt函數,這個sqrt函數就是開根的做用,它是Python自帶的模塊,咱們只須要import導入就好了,好的咱們開始用這個模塊來開根:

 

 

 

5).按位運算

按位運算,那麼什麼是位呢?

 

這裏的位指的是二進制位,按位運算就按位是指將一個數字轉換爲標準的8位二進制,而後這些二進制按位操做運算

 

&:按位與運算:按位相同則取1,不一樣取0

例: a=7&18        

7      二進制爲111              轉爲標準8位二進制    00000111

18    二進制爲10010         轉爲標準8位二進制     00010010

兩個做與運算得:                                                   00000010

最終結果爲2

 

|:按爲或運算:按位其中一位位1則取1,都不爲1則取0

例: a=7|18        

7  二進制爲111              轉爲標準8位二進制    00000111

18二進制爲10010         轉爲標準8位二進制    00010010

兩個做與運算得:                                              00010111

最終結果爲23

 

^:按位異或運算:按位不一樣則取1,相同取0

例: a=7^18        

7  二進制爲111              轉爲標準8位二進制    00000111

18二進制爲10010         轉爲標準8位二進制    00010010

兩個做與運算得:                                              00010101

最終結果爲21

 

~:按位翻轉,即~x=-(x+1)

 

例: a=~18   ~18=-(18+1)

結果爲-19

 

<<:按位左移,好比18即爲00010010,左移一個單位00100100

 

 

>>:按位左移,好比18即爲00010010,左移一個單位00001001

 

 

 

其餘操做符:就是小括號和正負號(+,-,注意這裏不等同於加減號),可是他們的優先級很高

 

好的,以上就是各類運算了,那麼相信聰明的你必定想到一個問題,如今這麼多種不一樣的操做符,若是都放在一塊兒計算,怎麼知道先算誰後算誰呢?這個確實是個問題,因此這就有了運算優先級了

 

 

運算優先級

 

這裏直接用一個圖來解釋,三角形由上到下,依次優先級由高到底

 

 

 

 

這裏用一個例子說一下爲何正負號在冪運算優先級之上:

 

 

 

 

字符串和輸入輸出

 

什麼是字符串

 

凡是用‘’(引號)引發來的都叫字符串,好比:

 

 

 

這個引號能夠是單引號(’’),也能夠是雙引號(「」),也能夠是三引號(’’’’’’)

 

注意:三種形式的引號必須成對出現,否則報錯:

 

 

報錯提示就是說你的符號沒有一個合理的結尾,換句話就是你的符號沒有成對出現。

 

而且字符串也是數據類型的一種,因此數據類型到如今咱們學的數據類型有:int,str,float

 

那麼這裏就有個很重要的知識點

數據類型轉換:

 

1).整形轉字符串:用str函數轉換

 

 

2).整形轉浮點型:用float函數

 

 

 

3).字符串轉整形:用int函數

注意:字符串轉整形有個前提,字符串裏自己是個數字,否則報錯

 

 

 

 

三種不一樣數據類型之間的轉換圖解:

 

 

 

 

建立字符串的方法:

 

1).直接使用引號:

這個上面已經說了 例:’python’

 

2).用函數str()

 

 

 

利用str函數來建立函數,括號內能夠是數字,也能夠是字符串,但不能是未定義的變量:

 

 

 

字符串操做

  

字符串是什麼前面你們都瞭解了吧,字符串在Python中是個很重要的概念,它是一個數據類型(前面的int,float,str),又是一個數組類型(即一個容器,能夠存放多個數據的類型),仍是一個對象,既然是一個對象,則會有不少方法、屬性操做

 

如下是Python3下字符串的全部方法

 

 

 

注:因爲字符串的方法太多,下面就簡單講解幾個很是經常使用的方法就行,望各位看官耐心看下去

 

captalize:把整個字符串的第一個單詞的首字母大寫並返回

 

 

注意:

 

1).這裏使用了字符串的方法後,其實並不會修改test自身,只是返回了一個結果,若是須要修改test,則將修改後的結果從新賦值:

 

 

 

2).使用字符串的方法是最後要加「()」,沒有什麼特別的意思,這就是Python規定的  

 

 

casefold:把整個字符串的全部字符改成小寫,python3裏特有的

 

 

 

 

center(width):把字符串居中,並使用空格填充至長度 width 的新字符串

 

 

 

count(sub[, start[, end]]):返回 sub 在字符串裏邊出現的次數,start 和 end 參數表示索引範圍

 

索引即下標,從0開始。

 

 

上面這個test,其值對應索引就是下面的數字

 

好比這裏test = "abcdfjack":經過索引就能夠單獨取出數據

 

 

 

 

 

 

這裏count方法裏的1,4就是索引爲止,因爲索引1到4並無‘a’,因此返回0

 

decode(decode='strict'):把已知的編碼方式解碼爲Unicode

encode(encoding='utf-8', errors='strict'):以 encoding 指定的編碼格式對字符串進行編碼

 

endswith(sub[, start[, end]]):檢查字符串是否以 sub 子字符串結束,若是是返回 True,不然返回 False。start 和 end 參數表示範圍

 

 

 

 

startswith(prefix[, start[, end]]):檢查字符串是否以 prefix 開頭,是則返回 True,不然返回 False。start 和 end 參數能夠指定範圍檢查

 

 

 

 

expandtabs([tabsize=8]):把字符串中的製表符(即一個tab鍵位置,相信前面第一章裏Python的語法規則你已經學過了),\t轉換爲空格,如不指定參數,默認的空格數是 tabsize=8

 

 

 

 

這裏因爲都是空白的看不出效果,它確實是已經把\t轉爲空格了

 

find(sub[, start[, end]]):檢測 sub 是否包含在字符串中,若是有則返回索引值,不然返回 -1

 

 

 

 

rfind(sub[, start[, end]]):原理同 find() 方法,不過是從右邊開始查找

 

foramt:格式化字符串

 

 

index(sub[, start[, end]]):跟 find 方法同樣,不過若是 sub 不在 string 中會產生一個異常

 

 

 

 

rindex(sub[, start[, end]]):同理index() 方法,不過是從右邊開始

 

isalnum():若是字符串至少有一個字符而且全部字符都是字母或數字則返回 True,不然返回 False

 

 

 

isalpha():若是字符串至少有一個字符而且全部字符都是字母則返回 True,不然返回 False

  

 

isdecimal():若是字符串只包含十進制數字則返回 True,不然返回 False,這是python3特有

  

 

isdigit():若是字符串只包含數字則返回 True,不然返回 False

 

 

isnumeric():若是字符串中只包含數字字符,則返回 True,不然返回 False,同理isdigit方法相同

islower():若是字符串中至少包含一個區分大小寫的字符,而且這些字符都是小寫,則返回 True,不然返回 False

 

 

isspace():若是字符串中只包含空格,則返回 True,不然返回 False

 

 

istitle():若是字符串是標題化(全部的單詞都是以大寫開始,其他字母均小寫),則返回 True,不然返回 False

 

 

isupper():若是字符串中至少包含一個區分大小寫的字符,而且這些字符都是大寫,則返回 True,不然返回 False

 

 

join(sub):以字符串做爲分隔符,插入到 sub 中全部的字符之間

 

 

ljust(width):返回一個左對齊的字符串,並使用空格填充至長度爲 width 的新字符串

 

 

lower():轉換字符串中全部大寫字符爲小寫。

 

 

partition(sub):找到子字符串 sub,把字符串分紅一個 3 元組 (pre_sub, sub, fol_sub),若是字符串中不包含 sub 則返回 ('原字符串', '', '')

 

 

rpartition(sub):同理partition() 方法,不過是從右邊開始查找

replace(old, new[, count]):把字符串中的 old 子字符串替換成 new 子字符串,若是 count 指定,則替換不超過 count 次

 

 

rjust(width):返回一個右對齊的字符串,並使用空格填充至長度爲 width 的新字符串,同理ljust

 

split(sep=None, maxsplit=-1):不帶參數默認是以空格爲分隔符切片字符串,若是 maxsplit 參數有設置,則僅分隔 maxsplit 個子字符串,返回切片後的子字符串拼接的列表

 

 

splitlines(([keepends])):按照 '\n' 分隔,返回一個包含各行做爲元素的列表,若是 keepends 參數指定,則返回前 keepends 行

 

 

strip([chars]):刪除字符串前邊和後邊全部的空格,chars 參數能夠定製刪除的字符,可選

 

 

lstrip():去掉字符串左邊的全部空格

 

 

rstrip():去掉末尾(右邊)的空格,同理lstrip(),strip()

swapcase():翻轉字符串中的大小寫

 

 

title():返回標題化(全部的單詞都是以大寫開始,其他字母均小寫)的字符串

 

 

translate(table):根據 table 的規則(能夠由 str.maketrans('a', 'b') 定製,maketrans方法是python特有,用的較少)轉換字符串中的字符

 

 

這個方法和replace方法很相似,我的建議直接使用replace,這個translate步驟太多了。

 

upper():轉換字符串中的全部小寫字符爲大寫

 

 

zfill(width):返回長度爲 width 的字符串,原字符串右對齊,前邊用 0 填充

 

 

 

以上就是經常使用的字符串方法了,固然還有不少字符串方法,感興趣能夠本身去研究了,掌握了上面的方法都夠你處理平常任務了

 

 

 

字符串拼接:+

 

字符串也能夠拼接起來: 

 

 

 

除了用「+」還能夠用‘,’號,但並非真正意義的拼接,且中間會有一個空格

 

 

 

 

但記住必定不是加起來,並且不一樣類型的是不能拼接的,會報錯:

 

 

 

 

 

簡單輸入輸出

 

1).print輸出

 

固然就是前面你已經用到的print了。在Python2裏,print是一個語句。在Python3裏,print是一個函數了,既然是函數,天然就還有其餘功能了。先看文檔:

 

 

Sep參數不多用,你能夠忽略不計,end參數卻是常常用。

無論在Python2仍是3裏面,都是做打印而已,可是在打印的同時,print會自動加一個換行符(\n)換行

請看,我這什麼都沒打印,仍是換了一行。(我用的是Python3)

 

 

 

好的,此時我用end參數就能夠修改默認的換行符:

 

 

我把end參數等於一個空字符串後,print再也不自動換行了,後期你可能還會遇到換成其餘字符的,好比換成一個分隔符,佔位符等等的。

 

說到,那不得不提一個知識——轉義符「\」

 

這個轉義符有什麼用呢?它有兩個做用:

 

  • 邏輯斷行

  • 轉義特殊字符

 

邏輯斷行:

 

先看例子:

 

 

因爲由於內容太多,一行放不完,這時咱們就能夠用\在結尾做邏輯斷行:

 

 

 

 

可是對於Python而言,它發現你用了‘\’做邏輯斷行它就知道這上下實際上是一行。

 

轉義特殊字符

 

咱們先看個例子,打印一個文件路徑:

 

 

                                           

乍一看好像沒什麼問題對吧?是的,這個它確實沒問題,嘻嘻。

 

那麼再看下這個路徑呢:

 

 

 

發現換行了對吧,由於什麼呢?由於它把」file\newfile」裏的」\n」當成一個換行符並轉義成換行符了,因此會換行。

那麼咱們不想讓它這樣呢?辦法是有的,換行符關鍵的就是這個反斜槓(\)嘛,它自身是一個換行符,那我讓轉義本身呢:

 

 

可行,問題已解決。

 

那麼假如說我這個文件路徑很長呢:path3 = 'c\now\now\now\new\new\now\new....'

這裏你就可使用原始字符串——‘r’了:

 

 

好的,這個問題解決了

 

那麼若是這個字符串結尾處恰好是一個轉義符又怎麼樣呢:

 

 

 

用原始字符串的方法不行,怎麼辦呢?除告終尾處,前面的咱們都用原始字符串解決了對吧?那麼把這結尾單獨轉義一下唄:

 

 

 

其餘的轉義符:(暫且不用記,用到的時候再回過來看,用多了就記住了)

 

\

轉義字符;換行續寫

\'

單引號

\"

雙引號

\a

發出系統響鈴聲

\b

退格符

\n

表示換行

\t 

製表符,即一個tab鍵的位置

\v

縱向製表符

\r

回車符

\f

換頁符

\o

八進制數表明的字符

\x

十六進制數表明的字符

\0

表示一個空字符

\\

表示\字符自己,反斜槓

#

註釋字符

 

 

input輸入

 

學完前面的知識,相信你已經愈來愈以爲上面那些功能不夠你用了,老是很死板的設定一個變量值,而後作個運算或者轉換處理而後輸出,你可能漸漸以爲這樣有點low了對吧,你想用更高級點的語法,由於你發現市面上不少軟件或者網站都有讓用戶本身輸入的選項,用戶輸入什麼,這個數據它就永遠是什麼。那麼Python裏有沒有這個功能呢?那固然是有的,這個功能就是Input函數的功能

當咱們敲下input()時回車:

 

 

空白處就是須要用戶本身輸入,輸入什麼它就會返回什麼:

 

 

那麼這個值咱們天然也能夠用變量臨時存儲起來:

 

 

  

注意:在Python3中input函數會把你輸入的任何數據自動轉爲字符串:

 

 

 

 

那麼有朋友想到個問題,既然input會自動轉爲字符串,那麼我就是要整形怎麼辦呢?簡單,類型轉換啊:

 

 

在Python2中,input輸入什麼這個值就是什麼類型,也就是說你要提早設定數據類型:

 

 

 

爲何報錯呢,是由於input它不識別你這「asdf」,發現「asdf」是未定義的值

因此要加引號才行:

 

 

因此若是你使用的時Python2的話怎麼辦?Python2裏有個raw_input函數:

 

 

換句話說,Python2中的raw_input等同於Python3裏的input

 

其實input函數還能夠做提示的:

 

 

 

 

有提示也有輸入,這纔是真正的與用戶達到交互式了。那麼咱們能夠得出結論,input函數即有輸入也有輸出的功能

 

字符集編碼

 

學完上面的字符數據操做,相信聰明的你想過這些字符數據是怎麼存放在磁盤裏的對吧?從第一章的計算機常識裏你已經得知計算機只認二進制了,那麼存放字符數據天然也是二進制,接着又帶來一個新的問題,如今全國各地的程序員,因爲語言的不一樣,存都是二進制,然而要用的時候,必定有一個你們默許的規則,否則會形成不堪的後果。這個規則就是編碼了。

 

 

字符集編碼介紹

 

什麼是編碼

 

編碼是國際定義的標準,簡單的理解就是計算機中存儲數據的格式,在計算機中數據都是以二進制的0和1來進行存儲,因此爲了把二進制轉換爲人類能夠理解的內容就須要編碼來進行轉換。而人類寫的字符要讓計算機識別,也須要轉換編碼。

而且高級開發語言,都須要解釋器解釋爲機器能夠認識的字符。

 

編碼的起源歷史

 

最先出現編碼是美國的ASCII,可是ASCII只有26個英文字母以及一些標點符號,歐洲國家爲了更方便的使用,也設計了一套EASCII,包含了拉丁字符,慢慢的中國計算機行業發展起來後也設計了一套編碼GB2312,收錄了大部分經常使用簡體字,而且包括日韓文裏使用的漢字,臺灣同胞由於使用繁體字,也設計了一套編碼big5。後面國人但願統一一下,在BG2312之上作了個升級版GBK,收錄更多的簡體字,包括了繁體字以及少數名族的使用的文字;日本和韓國也都各自設計了本身的一套編碼。而後不少國家都有了本身的一套的編碼。

 

因此市面上就有了一大批的編碼,國與國之間交流也困難,那麼既然咱們人與人之間交流須要一個通用的語言,計算機界也有了這麼一套通用語言,最後國際協會決定統一下編碼,推出一套萬國碼——Unicode,整合了全球全部的編碼,能夠直接支持全球全部的語言,就像英語是全球通用的語言同樣了,而且Unicode直接解決了字符與二進制之間的映射關係,不用再考慮不一樣語言的存取問題了。

不過Unicode還有一個問題,因爲Unicode字符集是一個字符佔2-4字節的,因爲最開始使用ASCII時一個字母是隻佔一個字節的,這樣就很浪費空間了(好比‘age’這個單詞使用Unicode須要佔6個字節,但使用ASCII碼只佔3個字節)。因此國際協會又想了一招,作了個優化,出現了一個新的編碼——UTF-8,UTF-8默認使用1個字符,不夠則增長,最多4個字節。英文佔1個字節、歐洲語系佔2個、東亞佔3個,其它及特殊字符佔4個。

 

注意:

 

  • UTF-8仍是屬於Unicode,只是Unicode其中一個優化版本,其實還有其餘UTF-16,Utf-32之類的。

  •  UTF-8編碼英文只佔1一個字節,中文佔三個字節

  •  GBK、GB2312編碼下中文僅佔兩個字節,因此國內不少公司或者網站仍是使用的GBK或BG2312

        

 

python2和python3的編碼

 

 

瞭解完字符集編碼,是否是以爲很簡單,先別這麼認定,由於它但是最容易出問題的,而且在Python中這個編碼問題一直是老生常談的問題,不少程序員在工做以後好幾年都沒有真正理解字符編碼,還有一部分程序員自認爲本身理解了,當在開發中才發現其實並無真正理解。

 

在Python3裏是Unicode編碼,Python2裏是ASCII編碼(當時Python2出現時尚未Unicode編碼)

 

如今咱們看下Python2和Python3下不一樣的編碼,打開操做系統的終端進入python:

 

 

 

 

 

在聲明字符串時在前面加u表示以Unicode形式,加b表示以bytes形式。Python3裏用b轉字節報錯實際上是對的,這裏下面會解釋

看到上面的簡單例子,確實發現Python兩個版本的編碼不一樣了吧。'\xd6\xd0\xb9\xfa'這個是16進制的字節,這裏要說一下,咱們知道二進制因爲太長好比00101110011之類,要表示一個數據的字節太長了不方便,因此存儲是的的確確以二進制存儲的,只是用十六進制來表示。那麼這裏有個問題,就算Python3默認是unicode可是無論怎麼打印仍是同樣的,那麼就能夠確定,Python3必定自動幫咱們作了編碼解碼操做。而Python2裏沒有自動幫助咱們,在Python兩個版本里都有一個解碼(decode)和編碼(encode)方法,也就是前面字符串操做裏的這兩個方法,在這裏就要派上用場了,咱們就能夠用這兩個方法手動編碼解碼:

 

 

 

 

decode方法須要給一個參數,這個參數必須字符以前的字符編碼匹配,全部的字節解碼都會解碼成Unicode

好比這裏的‘中國’,咱們用gbk就正確解碼了。可是有朋友要問了,咱們這裏沒有給字符集編碼它怎麼本身就存儲成gbk編碼了,由於我這裏使用的是windows的cmd終端,這個終端默認是使用gbk的,因此給存成gbk了。使用chcp命令能夠查看得知:936即表明gbk編碼了

 

 

不信的話能夠用encode方法驗證:

 

 

 

這裏編碼成gbk以後確實和最初的test同樣的。

 

encode方法須要給一個參數,這個參數能夠是任意字符集編碼

既然能夠編碼成任意字符集編碼,編譯成utf-8和以前的對比:

 

 

 

這個「涓x浗」是啥啊?這個其實就是亂碼了,爲何呢?由於Python2裏的print語句會帶有一點讀取的意思,因此讀取的時候因爲「中國」原本就是gbK的(windows的cmd終端自動設置了),這裏解碼成unicode以後編碼成utf-8確定不識別啊,由於沒有對應的編碼集能夠正確解碼,只是恰好在編碼集裏有這些字符集被錯誤解釋出來了,可是是毫無心義的字符。有朋友想到了,前面不是說已經支持中文了嗎?確實支持了,可是支持的是Unicode啊,utf-8並非支持,雖然utf-8也是unicode裏的一個分支。而上面的test_deco就是unicode啊,print的時候是正常的。

 

那麼Python2爲何會形成這種難以想象的問題呢?先看下類型看看呢:

 

 

這什麼狀況?test是gbk的字節,test_utf是utf-8的字節,怎麼會顯示的類型是字符串呢?答案是Python2裏bytes = str,是的在Python2裏竟然把字節和字符等同了(前面咱們說了字節和字符徹底是不一樣的),這就是最根本的問題所在,並且還有一種新的字符類型unicode。這樣也側面說明了Python2裏字符類型只有str和unicode

 

而Python3裏:

 

 

 

因爲Python3裏字符串方法裏已經不存在decode方法(由於已經默認是unicode編碼了)

 

 

編碼爲utf-8以後看下類型:

 

 

 

Python3裏是一切正常的,由於編碼原本就會變成字節,而後交給計算機處理,咱們要查看和使用時再解碼的,這裏沒有Python2那麼特殊。

 

 

 

因此能夠得出結論:Python3裏的字符類型是str和bytes,python3裏btyes就是bytes,並不像Python2裏bytes等同於str,且python2裏的Unicode等同於Python3裏的str

 

 

 

總結

 

在python2裏,原本存儲的是字節,print時會成爲str 

 

但轉爲元祖類型就顯原型,在往後的操做時若是遇到這樣的狀況,使用for循環或者利用數組類型取數據的方法取出來就行:

 

若是在後期遇到編碼問題時你還是沒法理解,不知道怎麼解決,你可使用Python3操做,問題立馬解決。

使用編輯器操做時,一般會在文件開頭加一行此代碼:# coding:utf-8定義一個統一編碼,表示此文件裏通用該編碼:以防出現不可避免的問題

  

#!/usr/bin/env python 是linux操做系統下會使用的聲明,表示告訴linux運行文件時這是Python文件,以Python形式運行。

相關文章
相關標籤/搜索