最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Python中dbm模塊和shelve模塊的使用

 更新時間:2023年10月24日 09:15:55   作者:古明地覺的編程教室  
這篇文章主要為大家詳細(xì)介紹了Python中dbm模塊和shelve模塊的具體用法,文中的示例代碼簡潔易懂,對我們深入學(xué)習(xí)Python有一定的幫助,需要的可以參考下

dbm

DBM(DataBase Manager)是一種文件系統(tǒng),專門用于鍵值對的存儲,最初是在 Unix 平臺實現(xiàn),現(xiàn)在其它平臺也可以用。對于 KV 模型,DBM 提供了一個輕量級、高效的存儲解決方案。

總的來說,DBM 具有如下特點:

  • 簡單快速:非常簡單易用,讀取和寫入操作都很快,適合存儲少量數(shù)據(jù)。
  • 鍵值對存儲:數(shù)據(jù)是以鍵值對形式存儲的,你可以像操作 Python 字典一樣。
  • 文件存儲:數(shù)據(jù)存在具體的文件中,可以輕松地備份和轉(zhuǎn)移。
  • 不支持復(fù)雜查詢:如果需要執(zhí)行復(fù)雜查詢或需要關(guān)系型數(shù)據(jù)庫的功能,DBM 可能不是一個好選擇。

而 Python 標(biāo)準(zhǔn)庫提供了一個 dbm 模塊,它實現(xiàn)了 DBM 文件系統(tǒng)的功能,來看一下它的用法。

import dbm

# 第一個參數(shù)是文件名
# 第二個參數(shù)是模式,有以下幾種
#     r:只讀,要求文件必須存在,默認(rèn)就是這個模式
#     w:可讀可寫,要求文件必須存在
#     c:可讀可寫,文件不存在會創(chuàng)建,存在則追加
#     n:可讀可寫,文件不存在會創(chuàng)建,存在則清空
# 第三個參數(shù)是權(quán)限,用八進(jìn)制數(shù)字表示,默認(rèn) 0o666,即可讀可寫不可執(zhí)行
db = dbm.open("store", "c")

# 打開文件就可以存儲值了,key 和 value 必須是字符串或 bytes 對象
db["name"] = "S せんせい"
db["age"] = "18"
db[b"corporation"] = "小摩".encode("utf-8")

# 關(guān)閉文件,將內(nèi)容寫到磁盤上
db.close()

非常簡單,就像操作字典一樣,并且 key 是唯一的,如果存在則替換。執(zhí)行完后,當(dāng)前目錄會多出一個 store.db 文件。

我們打開它,然后讀取剛才寫入的鍵值對。

import dbm

db = dbm.open("store", "c")

# 獲取所有的 key,直接返回一個列表
print(db.keys())
"""
[b'corporation', b'name', b'age']
"""
# 判斷一個 key 是否存在,key 可以是字符串或 bytes 對象
print("name" in db, "NAME" in db)
"""
True False
"""
# 獲取一個 key 對應(yīng)的 value,得到的是 bytes 對象
print(db["name"].decode("utf-8"))
print(db[b"corporation"].decode("utf-8"))
"""
S せんせい
小摩
"""
# key 如果不存在,會拋出 KeyError,我們可以使用 get 方法
print(db.get("NAME", b"unknown"))
"""
b'unknown'
"""
# 當(dāng)然也可以使用 setdefault 方法,key 不存在時,自動寫進(jìn)去
print(db.setdefault("gender", b"female"))
"""
b'female'
"""
print(db["gender"])
"""
b'female'
"""

非常簡單,當(dāng)你需要存儲的數(shù)據(jù)量不適合放在內(nèi)存中,但又沒必要引入數(shù)據(jù)庫,那么不妨試試使用 dbm 模塊吧。

當(dāng)然啦,dbm 雖然很方便,但它只能持久化 bytes 對象,字符串也是轉(zhuǎn)成 bytes 對象之后再存儲的。所以除了 dbm 之外,還有一個標(biāo)準(zhǔn)庫模塊 shelve,它可以持久化任意對象。

shelve

shelve 的使用方式和 dbm 幾乎是一致的,區(qū)別就是 shelve 的序列化能力要更強(qiáng),當(dāng)然速度自然也就慢一些。

import shelve

# 第二個參數(shù)表示模式,默認(rèn)是 c
# 因此文件不存在會創(chuàng)建,存在則追加
sh = shelve.open("shelve")

sh["name"] = ["S 老師", "高老師", "電烤??架"]
sh["age"] = {18}
sh["job"] = {"tutu": "大學(xué)生", "xueer": "醫(yī)生"}

# 關(guān)閉文件,刷到磁盤中
sh.close()

執(zhí)行完之后,本地會多出一個 shelve.db 文件,下面來讀取它。

import shelve

sh = shelve.open("shelve")

print(sh["name"])
print(sh["name"][2] == "電烤??架")
"""
['S 老師', '高老師', '電烤??架']
True
"""
print(sh["age"])
"""
{18}
"""
print(sh["job"])
"""
{'tutu': '大學(xué)生', 'xueer': '醫(yī)生'}
"""

sh.close()

讀取出來的就是原始的對象,我們可以直接操作它。

然后自定義類的實例對象也是可以的。

import shelve

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def print_info(self):
        return f"name is {self.name}, age is {self.age}"

sh = shelve.open("shelve")

p = People("群主", 58)
# 將類、和該類的實例對象存儲進(jìn)去
sh["People"] = People
sh["p"] = p
sh.close()

執(zhí)行完之后,我們打開它。

import shelve

sh = shelve.open("shelve")

# 需要注意的是,People 是我們自己定義的類
# 如果你想要將其還原出來,那么該類必須要出現(xiàn)在當(dāng)前的命名空間中
try:
    sh["People"]
except AttributeError as e:
    print(e)
    """
    Can't get attribute 'People' on <module ...>
    """

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def print_info(self):
        return f"name is {self.name}, age is {self.age}"

print(sh["People"] is People)
"""
True
"""
print(sh["p"].print_info)
"""
name is 群主, age is 58
"""
print(sh["People"]("群主", 38).print_info)
"""
name is 群主, age is 38
"""

這就是 shelve 模塊,非常強(qiáng)大,當(dāng)然它底層也是基于 pickle 實現(xiàn)的。如果你不需要存儲復(fù)雜的 Python 對象,只需要存儲字符串的話,那么還是推薦 dbm。

然后在使用 shelve 的時候,需要注意里面的一個坑。

import shelve

# 打開文件,設(shè)置鍵值對
sh = shelve.open("shelve")
sh["name"] = "古明地覺"
sh["score"] = [80, 80, 80]
sh.close()

# 重新打開文件,修改鍵值對
sh = shelve.open("shelve")
sh["name"] = "芙蘭朵露"
sh["score"].append(90)
sh.close()

# 再次重新打開文件,查看鍵值對
sh = shelve.open("shelve")
print(sh["name"])
print(sh["score"])
"""
芙蘭朵露
[80, 80, 80]
"""
sh.close()

第一次打開文件創(chuàng)建兩個鍵值對,第二次打開文件將鍵值對修改,第三次打開文件查看鍵值對。但是我們發(fā)現(xiàn) sh["name"] 變了,而 sh["score"] 卻沒變,這是什么原因?

當(dāng)我們修改 name 時,采用的是直接賦值的方式,會將原本內(nèi)存里的值給替換掉。而修改 score 時,是在原有值的基礎(chǔ)上做 append 操作,它的內(nèi)存地址并沒有變。

所以可變對象在本地進(jìn)行修改,shelve 默認(rèn)是不會記錄的,除非創(chuàng)建新的對象,并把原有的對象給替換掉。所以 sh["score"].append(90) 之后,sh["score"] 仍是 [80, 80, 80],而不是 [80, 80, 80, 90]。

因為 shelve 沒有記錄對象自身的修改,如果想得到期望的結(jié)果,一種方法是把對象整體換掉。也就是讓 sh["score"] = [80, 80, 80, 90],這樣等于是創(chuàng)建了一個新的對象并重新賦值,是可行的。

或者你在打開文件的時候,多指定一個參數(shù) writeback。

import shelve

# 打開文件,設(shè)置鍵值對
sh = shelve.open("shelve")
sh["name"] = "古明地覺"
sh["score"] = [80, 80, 80]
sh.close()

# 重新打開文件,修改鍵值對
sh = shelve.open("shelve", writeback=True)
sh["name"] = "芙蘭朵露"
sh["score"].append(90)
sh.close()

# 再次重新打開文件,查看鍵值對
sh = shelve.open("shelve")
print(sh["name"])
print(sh["score"])
"""
芙蘭朵露
[80, 80, 80, 90]
"""
sh.close()

可以看到都發(fā)生改變了,但這個參數(shù)會導(dǎo)致額外的內(nèi)存消耗。當(dāng)指定 writeback=True 的時候,shelve 會將讀取的對象都放到一個內(nèi)存緩存當(dāng)中。比如我們操作了 20 個持久化的對象,但只修改了一個,剩余的 19 個只是查看并沒有做修改,但當(dāng) sh.close() 的時候,會將這 20 個對象都寫回去。

因為 shelve 不知道你會對哪個對象做修改,所以不管你是查看還是修改,都會放到緩存當(dāng)中,然后再一次性都寫回去。這樣就會造成兩點影響:

  • shelve 會把我們使用的對象放到內(nèi)存的另一片空間中,等于是額外拷貝了一份。
  • 雖然操作了 N 個對象,但只修改了 1 個,而 shelve 會把 N 個對象都重新寫回去,從而造成性能上的問題,導(dǎo)致效率降低。

因此加不加這個參數(shù),由具體情況決定。

綜上所述,Python 算是自帶了小型數(shù)據(jù)庫,看看能不能在合適的場景中把它用上。

到此這篇關(guān)于詳解Python中dbm模塊和shelve模塊的使用的文章就介紹到這了,更多相關(guān)Python dbm shelve內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python使用切片快速刪除列表數(shù)據(jù)

    Python使用切片快速刪除列表數(shù)據(jù)

    在?Python?中,列表(list)是一種常用的數(shù)據(jù)結(jié)構(gòu),支持動態(tài)增刪改查操作,但切片(slice)提供了一種更高效、更靈活的方式來刪除或修改列表的連續(xù)部分,本文將詳細(xì)介紹如何使用切片快速刪除列表數(shù)據(jù),需要的朋友可以參考下
    2026-04-04
  • python 比較字典value的最大值的幾種方法

    python 比較字典value的最大值的幾種方法

    這篇文章主要介紹了python 比較字典value的最大值,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Flask學(xué)習(xí)之全局異常處理詳解

    Flask學(xué)習(xí)之全局異常處理詳解

    Flask是一個基于Python的Web框架,它提供了全局異常處理的機(jī)制來捕獲和處理應(yīng)用程序中的異常,下面就帶大家深入了解一下Flask是如何實現(xiàn)異常處理的,希望對大家有所幫助
    2023-06-06
  • 一文詳解Python中實現(xiàn)單例模式的幾種常見方式

    一文詳解Python中實現(xiàn)單例模式的幾種常見方式

    這篇文章主要為大家介紹了Python中實現(xiàn)單例模式的幾種常見方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 超全Python圖像處理講解(多模塊實現(xiàn))

    超全Python圖像處理講解(多模塊實現(xiàn))

    這篇文章主要介紹了超全Python圖像處理講解(多模塊實現(xiàn)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 基于Faker生成測試數(shù)據(jù)的示例代碼

    基于Faker生成測試數(shù)據(jù)的示例代碼

    Faker是用來生成測試數(shù)據(jù)的Python包,可以很方便地生成各種測試數(shù)據(jù),支持中文,支持命令行模式,下面小編就來和大家詳細(xì)講講它的具體使用吧
    2025-06-06
  • Python循環(huán)結(jié)構(gòu)全面解析

    Python循環(huán)結(jié)構(gòu)全面解析

    循環(huán)中的代碼會執(zhí)行特定的次數(shù),或者是執(zhí)行到特定條件成立時結(jié)束循環(huán),或者是針對某一集合中的所有項目都執(zhí)行一次,這篇文章給大家介紹Python循環(huán)結(jié)構(gòu)解析,感興趣的朋友跟隨小編一起看看吧
    2025-06-06
  • python使用Berkeley DB數(shù)據(jù)庫實例

    python使用Berkeley DB數(shù)據(jù)庫實例

    這篇文章主要介紹了python使用Berkeley DB數(shù)據(jù)庫的方法,以實例形式講述了完整的操作過程,并總結(jié)了具體的操作步驟,非常具有實用性,需要的朋友可以參考下
    2014-09-09
  • 用Python分析3天破10億的《我不是藥神》到底神在哪?

    用Python分析3天破10億的《我不是藥神》到底神在哪?

    我不是藥神這部劇真的是很火,三天破10億。接下來腳本之家小編給大家?guī)砹擞肞ython來看3天破10億的《我不是藥神》到底神在哪?感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-07-07
  • 用Q-learning算法實現(xiàn)自動走迷宮機(jī)器人的方法示例

    用Q-learning算法實現(xiàn)自動走迷宮機(jī)器人的方法示例

    這篇文章主要介紹了用Q-learning算法實現(xiàn)自動走迷宮機(jī)器人的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評論

饶平县| 舒城县| 桂东县| 肥东县| 莒南县| 武义县| 惠安县| 乌恰县| 汝城县| 卢龙县| 漳平市| 长治市| 五莲县| 北流市| 海晏县| 车致| 广安市| 巴林右旗| 巴中市| 肃宁县| 高淳县| 九江县| 突泉县| 涿鹿县| 太和县| 榆树市| 满城县| 永胜县| 东源县| 高安市| 玉屏| 大余县| 中宁县| 元谋县| 大方县| 汉川市| 石首市| 阿拉善左旗| 西安市| 济南市| 麻城市|