成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

pickle和cPickle:Python對象的序列化(下)

LeviDing / 2915人閱讀

摘要:重構(gòu)對象的問題當(dāng)與你自己的類一起工作時,你必須保證類被腌漬出現(xiàn)在讀取的進(jìn)程的命名空間中。因?yàn)槭褂弥刀荒鼙浑鐫n的類,可以定義和來返回狀態(tài)的一個子集,才能被腌漬。腌漬和反腌漬該圖來創(chuàng)建一個結(jié)點(diǎn)集合。

  

承接上文 pickle和cPickle:Python對象的序列化(上) 。

重構(gòu)對象的問題

當(dāng)與你自己的類一起工作時,你必須保證類被腌漬出現(xiàn)在讀取pickle的進(jìn)程的命名空間中。只有該實(shí)例的數(shù)據(jù)而不是類定義被腌漬。類名被用于在反腌漬時,找到構(gòu)造器(constructor)以創(chuàng)建新對象。以此——往一個文件寫入一個類的實(shí)例為例:

pythontry:
    import cPickle as pickle
except:
    import pickle
import sys

class SimpleObject(object):

    def __init__(self, name):
        self.name = name
        l = list(name)
        l.reverse()
        self.name_backwards = "".join(l)
        return

if __name__ == "__main__":
    data = []
    data.append(SimpleObject("pickle"))
    data.append(SimpleObject("cPickle"))
    data.append(SimpleObject("last"))

    try:
        filename = sys.argv[1]
    except IndexError:
        raise RuntimeError("Please specify a filename as an argument to %s" % sys.argv[0])

    out_s = open(filename, "wb")
    try:
        # 寫入流中
        for o in data:
            print "WRITING: %s (%s)" % (o.name, o.name_backwards)
            pickle.dump(o, out_s)
    finally:
        out_s.close()

在運(yùn)行時,該腳本創(chuàng)建一個以在命令行指定的參數(shù)為名的文件:

python$ python pickle_dump_to_file_1.py test.dat

WRITING: pickle (elkcip)
WRITING: cPickle (elkciPc)
WRITING: last (tsal)

一個在讀取結(jié)果腌漬對象失敗的簡化嘗試:

pythontry:
    import cPickle as pickle
except:
    import pickle
import pprint
from StringIO import StringIO
import sys


try:
    filename = sys.argv[1]
except IndexError:
    raise RuntimeError("Please specify a filename as an argument to %s" % sys.argv[0])

in_s = open(filename, "rb")
try:
    # 讀取數(shù)據(jù)
    while True:
        try:
            o = pickle.load(in_s)
        except EOFError:
            break
        else:
            print "READ: %s (%s)" % (o.name, o.name_backwards)
finally:
    in_s.close()

該版本失敗的原因在于沒有 SimpleObject 類可用:

python$ python pickle_load_from_file_1.py test.dat

Traceback (most recent call last):
  File "pickle_load_from_file_1.py", line 52, in 
    o = pickle.load(in_s)
AttributeError: "module" object has no attribute "SimpleObject"

正確的版本從原腳本中導(dǎo)入 SimpleObject ,可成功運(yùn)行。
添加:

pythonfrom pickle_dump_to_file_1 import SimpleObject

至導(dǎo)入列表的尾部,接著重新運(yùn)行該腳本:

python$ python pickle_load_from_file_2.py test.dat

READ: pickle (elkcip)
READ: cPickle (elkciPc)
READ: last (tsal)

當(dāng)腌漬有值的數(shù)據(jù)類型不能被腌漬時(套接字、文件句柄(file handles)、數(shù)據(jù)庫連接等之類的),有一些特別的考慮。因?yàn)槭褂弥刀荒鼙浑鐫n的類,可以定義 __getstate__()__setstate__() 來返回狀態(tài)(state)的一個子集,才能被腌漬。新式類(New-style classes)也可以定義__getnewargs__(),該函數(shù)應(yīng)當(dāng)返回被傳遞至類內(nèi)存分配器(the class memory allocator)(C.__new__())的參數(shù)。使用這些新特性的更多細(xì)節(jié),包含在標(biāo)準(zhǔn)庫文檔中。

環(huán)形引用(Circular References)

pickle協(xié)議(pickle protocol)自動處理對象間的環(huán)形引用,因此,即使是很復(fù)雜的對象,你也不用特別為此做什么。考慮下面這個圖:

上圖雖然包括幾個環(huán)形引用,但也能以正確的結(jié)構(gòu)腌漬和重新讀?。╮eloaded)。

pythonimport pickle

class Node(object):
    """
    一個所有結(jié)點(diǎn)都可知它所連通的其它結(jié)點(diǎn)的簡單有向圖。
    """
    def __init__(self, name):
        self.name = name
        self.connections = []
        return

    def add_edge(self, node):
        "創(chuàng)建兩個結(jié)點(diǎn)之間的一條邊。"
        self.connections.append(node)
        return

    def __iter__(self):
        return iter(self.connections)

def preorder_traversal(root, seen=None, parent=None):
    """產(chǎn)生器(Generator )函數(shù)通過一個先根遍歷(preorder traversal)生成(yield)邊。"""
    if seen is None:
        seen = set()
    yield (parent, root)
    if root in seen:
        return
    seen.add(root)
    for node in root:
        for (parent, subnode) in preorder_traversal(node, seen, root):
            yield (parent, subnode)
    return

def show_edges(root):
    "打印圖中的所有邊。"
    for parent, child in preorder_traversal(root):
        if not parent:
            continue
        print "%5s -> %2s (%s)" % (parent.name, child.name, id(child))

# 創(chuàng)建結(jié)點(diǎn)。
root = Node("root")
a = Node("a")
b = Node("b")
c = Node("c")

# 添加邊。
root.add_edge(a)
root.add_edge(b)
a.add_edge(b)
b.add_edge(a)
b.add_edge(c)
a.add_edge(a)

print "ORIGINAL GRAPH:"
show_edges(root)

# 腌漬和反腌漬該圖來創(chuàng)建
# 一個結(jié)點(diǎn)集合。
dumped = pickle.dumps(root)
reloaded = pickle.loads(dumped)

print
print "RELOADED GRAPH:"
show_edges(reloaded)

重新讀取的諸多節(jié)點(diǎn)(譯者注:對應(yīng)圖中的圓圈)不再是同一個對象,但是節(jié)點(diǎn)間的關(guān)系保持住了,而且讀取的僅僅是帶有多個引用的對象的一個拷貝。上面所說的可以通過測試各節(jié)點(diǎn)在pickle處理前和之后的id()值來驗(yàn)證。

python$ python pickle_cycle.py

ORIGINAL GRAPH:
 root ->  a (4299721744)
    a ->  b (4299721808)
    b ->  a (4299721744)
    b ->  c (4299721872)
    a ->  a (4299721744)
 root ->  b (4299721808)

RELOADED GRAPH:
 root ->  a (4299722000)
    a ->  b (4299722064)
    b ->  a (4299722000)
    b ->  c (4299722128)
    a ->  a (4299722000)
 root ->  b (4299722064)
  

原文 pickle and cPickle – Python object serialization - Python Module of the Week 的后半部分。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/45345.html

相關(guān)文章

  • Python 對象列化——pickle and cPickle

    摘要:對象序列化從這篇文章粗略翻譯的模塊可以實(shí)現(xiàn)任意的對象轉(zhuǎn)換為一系列字節(jié)即序列化對象的算法。的文檔明確的表明它不提供安全保證。而利用則可以控制序列化的細(xì)節(jié)。 Python 對象序列化——pickle and cPickle 從這篇文章粗略翻譯的pickle and cPickle pickle模塊可以實(shí)現(xiàn)任意的Python對象轉(zhuǎn)換為一系列字節(jié)(即序列化對象)的算法。這些字節(jié)流可以 被...

    Taonce 評論0 收藏0
  • picklecPicklePython對象列化(上)

    摘要:使用來創(chuàng)建一個表示該對象值的字符串。數(shù)據(jù)被序列化以后,你可以將它們寫入文件套接字管道等等中。如果你使用管道或者套接字,在通過連至另一端的連接傾倒所有對象推送數(shù)據(jù)之后,別忘了沖洗。 目的:Python對象序列化 可用性:pickle至少1.4版本,cPickle 1.5版本以上 pickle模塊實(shí)現(xiàn)了一種算法,將任意一個Python對象轉(zhuǎn)化成一系列字節(jié)(byets)。此過程也調(diào)用了s...

    Sanchi 評論0 收藏0
  • python標(biāo)準(zhǔn)庫學(xué)習(xí)之pickle模塊

    摘要:利用標(biāo)準(zhǔn)庫中的的模塊可以將對象轉(zhuǎn)換為一種可以傳輸或存儲的格式。主要方法模塊中有兩個主要函數(shù),它們是和。具體語法為返回一個字符串,而不是存入文件中。該方法用于反序列化,即將序列化的對象重新恢復(fù)成對象。除此之外,這兩個模塊的接口是幾乎完全相同。 對象存在于程序運(yùn)行時的內(nèi)存中,當(dāng)程序不再運(yùn)行時或斷電關(guān)機(jī)時,這些對象便不再存在。我現(xiàn)在想把對象保存下來,方便以后使用,這就是持久化技術(shù)。利用 py...

    寵來也 評論0 收藏0
  • Python基礎(chǔ)之(十一)數(shù)據(jù)存儲

    摘要:默認(rèn)為或者說,是以格式保存對象如果設(shè)置為或者,則以壓縮的二進(jìn)制格式保存對象。但是,要小心坑試圖增加一個坑就在這里當(dāng)試圖修改一個已有鍵的值時沒有報(bào)錯,但是并沒有修改成功。要填平這個坑,需要這樣做多一個參數(shù)沒有坑了還用循環(huán)一下 pickle pickle是標(biāo)準(zhǔn)庫中的一個模塊,在Python 2中還有一個cpickle,兩者的區(qū)別就是后者更快。所以,下面操作中,不管是用import pick...

    Songlcy 評論0 收藏0
  • Python列化安全問題

    摘要:反序列化安全問題一這一段時間使用做開發(fā),使用了存儲,閱讀了源碼,發(fā)現(xiàn)在存儲到過程中,利用了模塊進(jìn)行序列化以及反序列化正好根據(jù)該樣例學(xué)習(xí)一波反序列化相關(guān)的安全問題,不足之處請各位表哥指出。 Python 反序列化安全問題(一) 這一段時間使用flask做web開發(fā),使用了redis存儲session,閱讀了flask_session源碼,發(fā)現(xiàn)在存儲session到redis過程中,利用了...

    Amos 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<