⼀. 小資料池
在說小資料池之前. 我們先看⼀個概念. 什麼是程式碼塊:
根據提示我們從官⽅⽂檔找到了這樣的說法:
A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as standard input to the interpreter or specified as a command line argument to the interpreter) is a code block. A script command (a command specified on the interpreter command line with the ‘-c‘ option) is a code block. The string argument passed to the built-in functions eval() and exec() is a code block. A code block is executed in an execution frame. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block’s execution has completed.
粗略的翻譯:
python程式是由程式碼塊構成的. ⼀個程式碼塊的⽂本作為python程式執⾏的單元. 程式碼塊: ⼀個模組, ⼀個函式, ⼀個類,
甚⾄每⼀個command命令都是⼀個程式碼塊. ⼀個⽂件也是⼀ 個程式碼塊, eval()和exec()執⾏的時候也是⼀個程式碼塊
二、接下來我們來看一下小資料池is和 ==的區別
1、id( )
透過id( )我們可以檢視到一個變數表示的值的記憶體地址
s = 'alex'
print(id(s)) # 4326667072
2、is和==
== 判斷左右兩段的值是否相等,是否一致
is 判斷左右兩端的記憶體地址是否一致,如果一致就返回True
注意:如果記憶體地址相同. 那麼值⼀定是相等的;如果值相等. 則不⼀定是同⼀個物件 。
3、小資料池.:⼀種資料快取機制. 也被稱為駐留機制.
小資料池只針對: 整數, 字串, 布林值. 其他的資料型別不存在駐留機制 。
對於整數, Python官⽅⽂檔中這麼說:
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined.對於字串:
Incomputer science, string interning is a method of storing only onecopy of each distinct string value, which must be immutable. Interning strings makes some stringprocessing tasks more time- or space-efficient at the cost of requiring moretime when the string is created or interned. The distinct values are stored ina string intern pool. –引⾃維基百科
在python中對-5到256之間的整數會被駐留在記憶體中,將一定規則的字串快取,在使用的時候,記憶體中只會建立一個該資料的物件,儲存小資料池中,當使用的時候直接從
小資料池中獲取物件的記憶體引用,二不需要建立一個新的資料,這樣可以節省更多的記憶體。
-
優點:能夠提高一些字串、整數的處理速度,省去了建立物件的過程。
-
缺點:在”池“中插入或者建立新值會花費更多時間。
對於數字: -5~256是會被加到⼩資料池中的. 每次使⽤都是同⼀個物件.
對於字串:
- 如果字串的⻓度是0或者1, 都會預設進⾏快取
- 字串⻓度⼤於1, 但是字串中只包含字⺟, 數字, 下劃線時才會快取
- ⽤乘法的到的字串.
①. 乘數為1, 僅包含數字, 字⺟, 下劃線時會被快取. 如果包含其他字元, ⽽⻓度<=1 也會被駐存,
②. 乘數⼤於1 . 僅包含數字, 字⺟, 下劃線這個時候會被快取. 但字串⻓度不能⼤於20 - 指定駐留. 我們可以透過sys模組中的intern()函式來指定要駐留的內容.
a = 1000
b = 1000
print(a is b)
注意. 在py⽂件中.得到的結果是True, 但是在command中就不是了.
在程式碼塊內的快取機制是不⼀樣的. 在執⾏同⼀個程式碼塊的初始化物件的命令時, 會檢查是否其值是否已經存在, 如果存在, 會將其重⽤. 換句話說: 執⾏同⼀個程式碼塊時,
遇到初始化物件的命令時, 他會將初始化的這個變數與值儲存在⼀個字典中, 在遇到新的變數時, 會先在字典中查詢記錄, 如果有同樣的記錄那麼它會重複使⽤這個字典中的
之前的這個值. 所以在你給出的例⼦中, ⽂件執⾏時(同⼀個程式碼塊) 會把a, b兩個變數指向同⼀個物件.如果是不同的程式碼塊, 他就會看這個兩個變數是否是滿⾜⼩資料池的資料,
如果是滿⾜⼩資料池的資料則會指向同⼀個地址. 所以: a, b的賦值語句分別被當作兩個程式碼塊執⾏, 但是他們不滿⾜⼩資料池的資料所以會得到兩個不同的物件, 因⽽is判斷
返回False.
三、編碼
- ASCII : 最早的編碼. ⾥⾯有英⽂⼤寫字⺟, ⼩寫字⺟, 數字, ⼀些特殊字元. 沒有中⽂,8個01程式碼, 8個bit, 1個byte
- GBK: 中⽂國標碼, ⾥⾯包含了ASCII編碼和中⽂常⽤編碼. 16個bit, 2個byte
- UNICODE: 萬國碼, ⾥⾯包含了全世界所有國家⽂字的編碼. 32個bit, 4個byte, 包含了ASCII
- UTF-8: 可變⻓度的萬國碼. 是unicode的⼀種實現. 最⼩字元佔8位
英⽂: 8bit 1byte
歐洲⽂字:16bit 2byte
中⽂:24bit 3byte
在python3的記憶體中,在程式執行階段,使用的是unicode編碼。因為unicode是萬國碼,什麼內容都可以進行顯示,那麼在資料傳輸和儲存的時候由於unicode比較浪費時間和資源。需要把unicode轉村委utf-8或者gbk進行儲存。
在python中可以把文字資訊進行編碼。編碼以後的內容就可以進行傳輸了,編碼以後的資料都是bytes型別的資料,其實原來的資料只是被編碼了,並沒有改變資訊內容。
- bytes的表現形式:
-
英文 b' alex’ 引文的表現形式跟字串沒什麼區別
-
中文 b'\xe4\xb8\xad‘ 這是一個漢字的utf-8的bytes表現形式。
字串在傳輸時轉化成bytes=> encode(字符集)來完成
s = "alex"
print(s.encode("utf-8")) # 將字串編碼成UTF-8
print(s.encode("GBK")) # 將字串編碼成GBK
#結果:
b'alex'b'alex'
s = "中"
print(s.encode("UTF-8")) # 中⽂編碼成UTF-8
print(s.encode("GBK")) # 中⽂編碼成GBK
#結果:
b'\xe4\xb8\xad'
b'\xd6\xd0
解碼
s = "我叫李嘉誠"
print(s.encode("utf-8")) #
b'\xe6\x88\x91\xe5\x8f\xab\xe6\x9d\x8e\xe5\x98\x89\xe8\xaf\x9a'
print(b'\xe6\x88\x91\xe5\x8f\xab\xe6\x9d\x8e\xe5\x98\x89\xe8\xaf\x9a'.decode("utf-8")) # 解碼
編碼和解碼的時候都需要制定編碼格式.
#學習中遇到問題沒人解答?小編建立了一個Python學習交流群:153708845
s = "我是⽂字"
bs = s.encode("GBK") # 我們這樣可以獲取到GBK的⽂字
# 把GBK轉換成UTF-8
# ⾸先要把GBK轉換成unicode. 也就是需要解碼
s = bs.decode("GBK") # 解碼
# 然後需要進⾏重新編碼成UTF-8
bss = s.encode("UTF-8") # 重新編碼
print(bss)