亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

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

LeviDing / 2929人閱讀

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

  

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

重構(gòu)對(duì)象的問(wèn)題

當(dāng)與你自己的類(lèi)一起工作時(shí),你必須保證類(lèi)被腌漬出現(xiàn)在讀取pickle的進(jìn)程的命名空間中。只有該實(shí)例的數(shù)據(jù)而不是類(lèi)定義被腌漬。類(lèi)名被用于在反腌漬時(shí),找到構(gòu)造器(constructor)以創(chuàng)建新對(duì)象。以此——往一個(gè)文件寫(xiě)入一個(gè)類(lèi)的實(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:
        # 寫(xiě)入流中
        for o in data:
            print "WRITING: %s (%s)" % (o.name, o.name_backwards)
            pickle.dump(o, out_s)
    finally:
        out_s.close()

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

python$ python pickle_dump_to_file_1.py test.dat

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

一個(gè)在讀取結(jié)果腌漬對(duì)象失敗的簡(jiǎn)化嘗試:

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()

該版本失敗的原因在于沒(méi)有 SimpleObject 類(lèi)可用:

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

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

pickle協(xié)議(pickle protocol)自動(dòng)處理對(duì)象間的環(huán)形引用,因此,即使是很復(fù)雜的對(duì)象,你也不用特別為此做什么??紤]下面這個(gè)圖:

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

pythonimport pickle

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

    def add_edge(self, node):
        "創(chuàng)建兩個(gè)結(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ù)通過(guò)一個(gè)先根遍歷(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)

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

print
print "RELOADED GRAPH:"
show_edges(reloaded)

重新讀取的諸多節(jié)點(diǎn)(譯者注:對(duì)應(yīng)圖中的圓圈)不再是同一個(gè)對(duì)象,但是節(jié)點(diǎn)間的關(guān)系保持住了,而且讀取的僅僅是帶有多個(gè)引用的對(duì)象的一個(gè)拷貝。上面所說(shuō)的可以通過(guò)測(cè)試各節(jié)點(diǎn)在pickle處理前和之后的id()值來(lái)驗(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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/45345.html

相關(guān)文章

  • Python 對(duì)象列化——pickle and cPickle

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

    Taonce 評(píng)論0 收藏0
  • picklecPicklePython對(duì)象列化(上)

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

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

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

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

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

    Songlcy 評(píng)論0 收藏0
  • Python列化安全問(wèn)題

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

    Amos 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<