6. 小數據池-編碼-文件操作

来源:https://www.cnblogs.com/hq82/archive/2019/08/11/11336599.html
-Advertisement-
Play Games

一、小數據池 1. 小數據池定義 小數據池(常量池),一種數據緩存機制,也被稱為駐留機制。小數據池只針對: 整數、字元串、布爾值 。其他數據類型不存在駐留機制。 2. 各類型數據池限定 (1) 整型 在python中 5 ~ 256 之間的整數會被駐留在記憶體中。每次使用都是同一個對象。 (2) 字元 ...


一、小數據池

1. 小數據池定義

小數據池(常量池),一種數據緩存機制,也被稱為駐留機制。小數據池只針對:整數、字元串、布爾值。其他數據類型不存在駐留機制。

2. 各類型數據池限定

(1) 整型

在python中 -5 ~ 256 之間的整數會被駐留在記憶體中。每次使用都是同一個對象。

(2) 字元串

將一定規則的字元串緩存。在使用的時候,記憶體中只會創建一個該數據的對象。保存在小數據池中。當使用的時候直接從小數據池中獲取對象的記憶體應用。而不需要創建一個新的數據,這樣會節省更多的記憶體區域。

優點:能提高一些字元串,整數的處理速度。省略創建對象的過程

缺點:在“池”中創建或插入新的內容會花費更多的時間

a. 如果字元串的長度是0或者1, 都會預設進行緩存 
b. 字元串長度大於1, 但是字元串中只包含字母, 數字, 下劃線時才會緩存
c. 用乘法得到的字元串.
    ①. 乘數為1, 僅包含數字, 字母, 下劃線時會被緩存. 如果包含其他字元, 而長度<=1 也會被駐存, 
    ②. 乘數大於1 . 僅包含數字, 字母, 下劃 線這個時候會被緩存. 但字元串長度不能大於20 
d. 指定駐留留. 我們可以通過sys模塊中的intern()函數來指定要駐留留的內容.

>>> from sys import intern
>>> a = intern('alex.sb.com' * 10)
>>> b = intern('alex.sb.com' * 10)
>>> a is b
True

3. py文件與command小數據池區別

​ 在代碼塊內的緩存機制是不一樣的. 在執行同一個代碼塊的初始化對象的命令時, 會檢查其值是否已經存在, 如果存在, 會將其重用. 換句話說: 執行同一個代碼塊時, 遇到初始 化對象的命令時,他會將初始化的這個變數與 值存儲在一個字典中, 在遇到新的變數時, 會先在字典中查詢記錄, 如果有同樣的記錄那麼它會重覆使用這個字典中的之前的這個值. 所以在 你給出的例子中, 文件執行時(同一個代碼塊) 會把a, b兩個變數指向同一個對象. 如 果是不同的代碼塊, 他就會看這個兩個變數是否是滿足小數據池的數據, 如果是滿足小數據池的數據則會指向同一個地址. 所以: a, b的賦值語句分別被當作兩個代碼塊執行, 但是他們不滿足小數據池的數據所以會得到兩個不同的對象, 因而is判斷返回False.

​ py文件里. 一個代碼塊內部. 只會緩存int, str, bool 也有自己的小數據池。 緩存的範圍會比外面的代碼塊的數據池要大

​ (1). 數字。都會緩存。 運算的結果不緩存(-5~256 會緩存)

​ (2). 字元串。 預設的字元串都緩存. 如果有乘法。 遵循上方的結論

​ (3). 布爾值。 預設緩存

4. is 和 == 區別

查看記憶體地址:id(變數)   

is : 判斷左右兩端內容的記憶體地址是否一致. 如果返回True, 那可以確定這兩個變數量使 用的是同一個對象
== :判斷左右兩端的值是否相等. 是不是一致.

二、編碼

1. python2和python編碼

(1) python2 - ASCII

預設使用ASCII碼,所以不支持中文. 如果需要在Python2中更改編碼. 需要在文件的開始編寫。

# -- encoding:utf-8 -
(2) python3 - UTF-8
(1)ASCII : 最早的編碼.裡面有英文大寫字母,小寫字母,數字,一些特殊字元.沒有中文,8個01代碼,8b,1B  (2)GBK: 中文國標碼,裡面包含了ASCII編碼和中文常用編碼.16b, 2B
(3)UNICODE: 萬國碼, 里麵包含了全世界所有國家文字的編碼. 32b, 4B, 包含了了 ASCII
(4)UTF-8: 可變長度的萬國碼.是unicode的一種實現.最⼩字元占8位;
          英文8b,1B  歐文16b,2B  中文24bit,3B
          綜上, 除了了ASCII碼以外, 其他信息不能直接轉換.

2. 編解碼

​ 在python3的記憶體中。 在程式運⾏階段。 使用的是unicode編碼。 因為unicode是萬國碼。 什麼內容都可以進行顯示。 那麼在數據傳輸和存儲的時候由於unicode比較浪費空間和資源。 需要把 unicode轉存成UTF-8或者GBK 進行存儲。 怎麼轉換呢。 在python中可以把文字信息進行編碼。 編碼之後的內容就可以進行傳輸了。 編碼之後的數據是bytes類型的數據。其實啊。 還是原來的數據只是經過編碼之後表現形式發生了改變而已。

​ bytes的表現形式: (1)英⽂ b'alex' 英⽂的表現形式和字元串沒什麽兩樣 (2)中文 b'\xe4\xb8\xad' 這是一個漢字的UTF-8的bytes表現形式

(1) 舉例
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

備註:英⽂編碼之後的結果和源字元串一致.中文編碼之後的結果根據編碼的不同. 編碼結果也不同. 我們能看到. 一個中文的UTF-8編碼是3個位元組. 一個GBK的中文編碼是2個位元組. 編碼之後的類型就是bytes類型.在網路傳輸和存儲的時候我們python是保存和存儲的bytes 類型. 那麼在對方接收的時候. 也是接收的bytes類型的數據. 我們可以使用decode()來進行解碼操作. 把bytes類型的數據還原回我們熟悉的字元串

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'.decod e("utf-8"))  
s = "我是文字" 
bs = s.encode("GBK")    # 我們這樣可以獲取到GBK的文字 
# 把GBK轉換成UTF-8 
# 首先要把GBK轉換成unicode. 也就是需要解碼 
s = bs.decode("GBK")  # 解碼 
# 然後需要進行重新編碼成UTF-8 
bss = s.encode("UTF-8") # 重新編碼 
print(bss)

三、文件操作

1. 初始文件操作

​ 使用python來讀寫文件時非常簡單的操作。我們使用open()函數來打開一個文件,獲取文件句柄,然後通過文件句柄就可以進行各種文件操作。打開文件需要close()文件。可使用with上下文進行操作文件。

2. 文件操作模式

​ 文件操作流程:建立文件對象,調用文件方法進行操作,不要忘記關閉文件(文件不關閉的情況下,內容會放在緩存,雖然python會在最後自動把內容讀到磁碟)

(1) r(only-read)
f = open("file", "r")
# read逐個字元地全部讀取出,read可以指定參數,設定要讀取多少字元;無論一個英文字母還是一個漢字都是一個字元
f_read = f.read()
f = open('file1','r')
# readlines會把內容以列表的形式輸出
f_read = f.readlines() 
print(f_read)
f.close()
# 推薦讀取方式

#輸出一行內容輸出一個空行,一行內容一行空格... 因為文件中每行內容後面都有一個換行符,而且print()語句本身就可以換行,如果不想輸出空行,就需要使用下麵的語句:print(line.strip())
f = open('file1','r')
for line in f.readlines() 
  print(line) 
f.close()
# 讀取圖片、視頻流文件 - rb
f = open('file', rb)
(2) w(only-write)

​ 在進行操作前,文件中所有內容會被清空。由於Python3的預設編碼方式是Unicode,所以在寫入文件的時候需要調用utf8,以utf8的方式保存,這時pycharm(預設編碼方式是utf8)才能正確讀取,當讀取文件時,文件是utf8格式,pycharm也是utf8,就不需要調用了。寫入位元組文件wb

f = open('file1','w',encoding='utf8')  
f_w = f.write('hello world')
#有意思的是,這裡並不列印'hello world',只列印寫入多少字元
print(f_w)  
f.close()
(3) a(append)

​ 與w模式不同的是,a模式不會把原來內容清空,而是游標移到內容最後位置,繼續寫入新內容。比如在最後追加'hello world'

f = open('file1','a')
f_a = f.write('hello world')
#還是會列印寫入的字元數
print(f_a) 
f.close()
(4) 讀取大文件
num = 0
# 不要過早關閉文件,否則程式不能識別操作句柄f.
f.close() 
f = open('file','r')
# for內部把f變為一個迭代器,用一行取一行
for i in f:  
  num += 1
  if num == 5:
    i = ''.join([i.strip(),'hello world'])
  print(i.strip())
f.close()

3. 其他操作

(1) tell 和 seek
f = open('file','r')
print(f.tell())  #游標預設在起始位置
f.seek(10)    #把游標定位到第10個字元之後
print(f.tell())  #輸出10
f.close()
----------------------
f = open('file','w')
print(f.tell())  #先清空內容,游標回到0位置
f.seek(10)    
print(f.tell())
f.close()
----------------------
f = open('file','a')
print(f.tell())  #游標預設在最後位置
f.write('你好 世界')
print(f.tell())  #游標向後9個字元,仍在最後位置
f.close()
(2) flush

​ 同步將數據從緩存轉移到磁碟; 如實現進度條

import sys,time  #導入sys和time模塊
for i in range(40):
  sys.stdout.write('*')
  # flush的作用相當於照相,拍一張沖洗一張
  sys.stdout.flush()  
  time.sleep(0.2)

# 下麵代碼也能夠實現相同的功能
import time 
for i in range(40):
  # print中的flush參數
  print('*',end='',flush=True) 
  time.sleep(0.2)
(3) truncate - 截斷

不能是r模式下執行,w模式下,已經清空所有數據,使用truncate沒有任何意義,a模式下,截斷指定位置後的內容。

f = open('file','a')
# 只顯示6個位元組的內容(6個英文字元或三個漢字),後面的內容被清空
f.truncate(6) 
(4) 游標位置總結
#--------------------------游標總結head-----------------------------------
f = open('file','r')
print(f.read(6)) #6個字元
print(f.tell())  #位置12位元組,一個漢字兩個位元組
f.close()
 
f = open('file','r')
f.seek(6)      #6個位元組
print(f.tell())
f.close()
 
f = open('file','a')
# 游標預設在最後位置
print(f.tell())  
f.write('你好 世界')
# 游標向後9個位元組,一個漢字兩個位元組,仍在最後位置 182-->191
print(f.tell())  
f.close()
 
f = open('file','a',encoding='utf-8')
# 由於需要游標定位位置,所以也是位元組。只顯示6個位元組的內容(6個英文字母或三個漢字,一個漢字兩個位元組),後面的內容被清空。
print(f.truncate(6)) 
f.close()
(4) r+/w+/a+

​ r+:讀寫模式,游標預設在起始位置,當需要寫入的時候,游標自動移到最後

​ w+:寫讀模式,先清空原內容,再寫入,也能夠讀取

​ a+:追加讀模式,游標預設在最後位置,直接寫入,也能夠讀取。

f = open('file','a')
print(f.tell())  #末尾207位置
f.close()
 
f = open('file','r+')
print(f.tell())  #0位置
print(f.readline()) #讀取第一行
f.write('羊小羚')   #游標移到末尾207位置並寫入
print(f.tell())  #213位置
f.seek(0)     #游標移到0位置
print(f.readline())  #讀取第一行
f.close()
(5) 修改文件內容
由於數據存儲機制的關係,我們只能把文件1中的內容讀取出來,經過修改後,放到文件2中

f2 = open('file2','w',encoding='utf8')  #寫入的時候必須加utf8
f1 = open('file','r')
num = 0
for line in f1: #迭代器
  num += 1
  if num == 5:
    line = ''.join([line.strip(),'羊小羚\n'])  #裡面就是對字元串進行操作了
  f2.write(line)
f1.close()
f2.close()

4. with語句

可以同時對多個文件同時操作,當with代碼塊執行完畢時,會自動關閉文件釋放記憶體資源,不用特意加f.close() ,我們通過下麵的示例體會with的用法和好處。用with語句重寫8中的代碼

num = 0
with open('file','r') as f1,open('file2','w',encoding='utf8') as f2:
  for line in f1:
    num += 1
    if num == 5:
      line = ''.join([line.strip(),'羊小羚'])
    f2.write(line)

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文屬於SpringMVC的入門篇,屬於基礎知識,僅供學習分享使用,如有不足之處,還請指正。 ...
  • [TOC] java實現發簡訊功能 前言 如今發簡訊功能已經成為互聯網公司的標配,本篇文章將一步步實現java發送簡訊 考察了許多提供簡訊服務的三方,幾乎所有都需要企業認證才可以使用,這對於個人學習非常不方便。多方比較之後,選擇了騰訊雲(此處並非做廣告),原因有兩點: 1. 支持微信公眾號認證(門檻 ...
  • 單元測試根據級別不同可分為:單元測試、集成測試、系統測試、驗收測試、回歸測試 單元測試的更能特點:對代碼最基本單元(函數、方法)的測試、 給予特定條件判斷結果是否符合預期 相對整個程式的測試,單元測試簡化了測試任務 unittest 模塊 代碼組織: 斷言:assertEqual(值,表達式) 是否 ...
  • <! more https://t.zsxq.com/UnA2jIi 博客 1、 "Flink 從0到1學習 —— Apache Flink 介紹" 2、 "Flink 從0到1學習 —— Mac 上搭建 Flink 1.6.0 環境並構建運行簡單程式入門" 3、 "Flink 從0到1學習 —— ...
  • 類的構成 類(Class) 由3個部分構成 類的名稱:類名 類的屬性:一組數據 類的方法:允許對進行操作的方法 (行為) 定義類 創建對象 Student類擁有的屬性數據 __init__()方法 __init___方法傳遞參數 __init___方法總結 定義__str__()方法 當使用prin ...
  • FutureTask FutureTask是Future的實現,用來非同步任務的獲取結果,可以啟動和取消非同步任務,查詢非同步任務是否計算結束以及獲取最終的非同步任務的結果。通過get()方法來獲取非同步任務的結果,但是會阻塞當前線程直至非同步任務執行結束。一旦任務執行結束,任務不能重新啟動或取消,除非調用ru ...
  • **想看看你最近一年都在幹嘛?看看你平時上網是在摸魚還是認真工作?想寫年度彙報總結,但是苦於沒有數據?現在,它來了。** 這是一個能讓你瞭解自己的瀏覽歷史的Chrome瀏覽歷史記錄分析程式,當然了,他僅適用於Chrome瀏覽器或者以Chrome為內核的瀏覽器。 在該頁面中你將可以查看有關... ...
  • 1. 通過對象實例化 先實例化對象,通過對象.getClass方法實例化 2. 由於1中必須要先有對象,所以在沒有對象的情況下,可以通過類名稱.class方式 3. 通過Class類中的靜態方法 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...