1. 程式人生 > >python基礎之小數據池、代碼塊、編碼

python基礎之小數據池、代碼塊、編碼

文本 讓其 http 數據池 浪費 技術 ket 文字 soft

一、代碼塊。
if True:
  print(333)
  print(666)

while 1:
  a = 1
  b = 2
  print(a+b)

for i in ‘12324354‘:
  print(i)

雖然上面的縮進的內容都叫代碼塊,但是他不是python中嚴格定義的代碼塊。
python中真正意義的代碼塊是什麽?

塊是一個python程序的文本,他是作為一個單元執行的。
代碼塊:一個模塊,一個函數,一個類,一個文件等都是一個代碼塊。

而對於一個文件中的兩個函數,也分別是兩個不同的代碼塊:

def func():
  print(333)


class A:
  name = ‘xiaojing

交互模式下,每一行是一個代碼塊。

什麽叫交互方式?就是咱們在cmd中進入Python解釋器裏面,每一行代碼都是一個代碼塊
>>> i1 = 520 可以理解為這一行在一個文件中。
>>> i2 = 520 可以理解為這一行在另一個文件中。

技術分享圖片

二、id is ==

在Python中,id是什麽?id是內存地址,== 是比較的兩邊的數值是否相等,而 is 是比較的兩邊的內存地址是否相等。

如果內存地址相等,那麽這兩邊其實是指向同一個內存地址。

技術分享圖片

name = ‘shuaige‘ # 賦值


print(‘shuaige‘ == ‘shuaige‘) # 數值相同
name = ‘abc123‘
name1 = ‘abc123‘
print(id(name),id(name1)) # 2370269674608 2370269674608
在內存中id都是唯一的,如果兩個變量指向的值的id相同,就證明他們在內存中是同一個。
is 判斷的是兩個變量的id值是否相同。
如果is是True, == 一定是True。== 是True,is不一定是True

三、小數據池(緩存機制,駐留機制)

小數據池的應用的數據類型: 整數,一定規則的字符串,bool值

小數據池是python對內存做的一個優化:


python將 -5 ~256 的整數,以及一定規則的字符串,bool值,進行了緩存,就是提前在內存中創建了池(容器),
在這些容器裏固定的放了這些數據。
為什麽這麽做???
1,節省內存。
2,提高性能與效率。

int:對於整數來說,小數據池的範圍是 -5~256 ,如果多個變量都是指向同一個(在這個範圍內的)數字,他們在內存中指向的都是一個內存地址。
i1 = 110
i2 = 110

i3 = 110

技術分享圖片

一定規則的字符串?

1,字符串的長度為0或者1,默認都采用了駐留機制(小數據池)

技術分享圖片

2,字符串的長度>1,且只含有大小寫字母,數字,下劃線時,才會默認駐留。

技術分享圖片

3,用乘法得到的字符串,分兩種情況。

3.1 乘數為1時:僅含大小寫字母,數字,下劃線,默認駐留。

技術分享圖片

3.1.2含其他字符,長度<=1,默認駐留。

技術分享圖片

3.1.3含其他字符,長度>1,默認駐留

技術分享圖片

3.2 乘數>=2時:僅含大小寫字母,數字,下劃線,總長度<=20,默認駐留。

技術分享圖片

4,指定駐留。

技術分享圖片
from sys import intern
a = intern(hello!@*20)
b = intern(hello!@*20)
print(a is b)
#指定駐留是你可以指定任意的字符串加入到小數據池中,讓其只在內存中創建一個對象,多個變量都是指向這一個字符串。
技術分享圖片

四、代碼塊與小數據池的關系

同樣一段代碼,為什麽在交互方式中(cmd命令的終端)執行,和通過pycharm執行結果不同呢?

技術分享圖片
# pycharm 通過運行文件的方式執行下列代碼:
i1 = 520
i2 = 520
print(i1 is i2)  # 結果為True
通過交互方式中執行下面代碼:
>>> i1 = 520
>>> i2 = 520
>>> print(i1 is i2) #結果為False
技術分享圖片

那為什麽結果會不同呢?

在同一個代碼塊中的變量(數字,字符串),初始化對象的命令時,首先會從小數據池中找,如果沒有找到,它會將變量與值的對應關系放到一個字典中,
同一個代碼塊中的其他變量遇到初始化對象的命令,他會先從字典中尋找,如果存在相同的值,他會復用,指向的都是同一個內存地址。

所以,在pycharm中的兩行變量賦值中(實際上在同一個代碼塊中的賦值):
(如果這個變量不是數字或者字符串,那麽值相同,地址也是不同的)

s1 = 1000

s2 = 1000

print(s1 is s2) #True

而在cmd命令的終端中(交互模式),每一行都是一個代碼塊,因此在cmd命令的終端中,s1和s2是在不同的代碼塊,因此s1 is s2 是False

技術分享圖片

l1 = [1,2]
l2 = [1,2]
print(id(l1),id(l2)) # 1745841050760 1745840183304
print(l1 == l2) # True
print(l1 is l2) # False


在不同的代碼塊:初始化對象的命令時,首先從小數據池中尋找,如果在小數據池,那麽地址相同,如果不在小數據池中,則創建新的地址。

不同代碼塊中:

技術分享圖片
def func():
    i1 = 1000
    print(id(i1))


def func1():
    i2 = 1000
    print(id(i2))
func()
func1()
# 一個函數是一個代碼塊,因此這裏的i1的地址跟i2的地址不是同一個地址
技術分享圖片

總結:
同一代碼塊中:
如果變量在小數據池,那麽地址相同,
如果不在小數據池,那麽如果變量是數字或者字符串,也會復用地址,地址也相同,
如果變量不是數字或者字符串,那麽地址不同。

不同一代碼塊中:
如果變量在小數據池,那麽地址相同,
如果不在小數據池,那麽地址不同。


五、編碼二
ASCII: 字母,數字,特殊字符。
A: 0000 0010
B: 0000 0011
unicode: 萬國碼,包含世界上所有的文字。
創建之初:16位
A :0001 0010 0000 0010
中:0011 0010 0000 0110
升級:32 位
A :0000 0010 0100 0010 0000 0010 1000 0010
中:0001 0010 0010 0010 0000 0010 0010 0010
缺點:浪費資源。


對unicode 升級:utf-8:最少用8位表示一個字符。
A :0000 0010 8位
歐:0000 0010 0100 0010 16位
中:0000 0010 0001 0010 0000 0010 24位

GBK: 國標:字母,數字,特殊字符,中文。
A :0000 0010 8位
中:0000 0010 0001 0010 16位

1, 編碼之間不能互相識別。
2, 網絡傳輸,或者硬盤存儲的010101,必須是以非uniocde編碼方式的01010101.

3,大環境python3x:
str:內存(內部)編碼方式為Unicode,因此python3中的字符串不能直接用於網絡傳輸和硬盤存儲,為了解決這個問題,就出現了bytes
bytes:python的基礎數據類型之一,他和str相當於雙胞胎,str擁有的所有方法,bytes類型都適用。

區別:
英文字母:
str:
表現形式:s1 = ‘xiaohei‘
內部編碼方式:unicode


bytes:
表現形式:b1 = b‘xiaohei‘
內部編碼方式:非unicode

中文:
str:
表現形式:s1 = ‘小黑‘
內部編碼方式:unicode


bytes:
表現形式:b1 = b‘\xe5\xb0\x8f\xe9\xbb\x91‘
內部編碼方式:非unicode

如何使用:
你想將一部分內容(字符串)寫入文件,或者通過網絡socket傳輸,這樣這部分內容(字符串)必須轉化成bytes才可以進行。
在平時的代碼中,可以直接使用字符串。

具體使用方法:encode編碼 decode解碼(bytes擁有str的所有方法)

encode()不寫參數,默認編碼成utf-8

str ---> bytes encode 編碼
非中文可以使用encode(),也可直接在字符串前加一個 b 表示bytes
s1 = ‘xiaohei‘

b1 = b‘xiaohei‘ --->等於 b1 = s1.encode()
b2 = b1.upper()

print(s1, type(s1))

print(b1, type(b1))
print(b2, type(b2))

中文只能使用encode()
s1 = ‘小黑‘
b1 = s1.encode(‘utf-8‘)
b2 = s1.encode(‘gbk‘)
print(b1) # b‘\xe5\xb0\x8f\xe9\xbb\x91‘
print(b2) # b‘\xd0\xa1\xba\xda‘

bytes ---> str decode 解碼
b1 = b‘\xd0\xa1\xba\xda‘ #gbk的bytes
s2 = b1.decode(‘gbk‘) #對應用gbk的解碼
print(s2)

python基礎之小數據池、代碼塊、編碼