我不想用二进制存储它,所以我没有将它设置为“wb”,我该怎么办?

2024-06-07 09:07:42 发布

您现在位置:Python中文网/ 问答频道 /正文

import pickle

    class player :
        def __init__(self, name , level ):
            self.name = name
            self.level = level
        def itiz(self):
            print("ur name is {} and ur lvl{}".format(self.name,self.level))
    
    p = player("bob",12)
    with open("Player.txt","w") as fichier :
        record = pickle.Pickler(fichier)
        record.dump(p)

这是错误write()参数必须是str,而不是bytes


Tags: nameimportselfinitisdefrecordlevel
3条回答

我一直在尝试跟踪评论中的所有聊天内容,但没有一个对我有多大意义。您不想“以二进制形式存储”,但Pickle是一种二进制格式,因此选择Pickle作为序列化方法,就已经做出了决定。因此,您的简单答案就是您在主题行中所说的内容……使用“wb”而不是“w”,然后继续(当您读回文件时,请记住使用“rb”):

p = player("bob",12)
with open("Player.pic", "wb") as fichierx:
    pickle.dump( p, fichierx )

如果你真的想使用一种基于文本的格式…一些人类可读的东西,考虑到我在你的对象中看到的数据,这并不困难。只需将字段存储在dict中,将loadstore方法添加到对象中,并使用json库通过以JSON格式从磁盘读写dict来实现这些方法

据我所知,有一个合理的理由可以在你的数据周围添加一个“ascification”层,那就是如果你想能够复制/粘贴它,就像你通常使用SSH密钥、证书等做的那样。正如其他人所说,这并不能使你的数据更易于阅读……只是更容易移动,比如在电子邮件中。如果这是你想要的,尽管你没有这么说,那么我承认,上面所有的东西都会回到桌面上。在这种情况下,请把我所有的唠叨理解为“告诉我们你真正的要求是什么”

如果JSON是您考虑的选项,这里有一个实现:

import json

class Player(dict):
    def __init__(self, name, level, **args):

        super(Player, self).__init__()

        # This magic line lets you access a Player's data as attributes of the object, but have
        # them be stored in a dictionary (this object's alter ego).  It is possible to do this with an
        # explicit dict attribute for storage if you don't like subclassing 'dict' to do this.
        self.__dict__ = self

        # Normal initialization (but using attribute syntax!)
        self.name = name
        self.level = level

        # Allow for on-the-fly attributes
        for k,v in args.items():
            self[k] = v

    def itiz(self):
        print("ur name is {} and ur lvl{}".format(self.name, self.level))

    def dump(self, fpath):
        with open(fpath, 'w') as f:
            json.dump(self, f)

    @staticmethod
    def load(fpath):
        with open(fpath) as f:
            return Player(**json.load(f))


p = Player("bob", 12)
print("This iz " + p.name)
p.occupation = 'Ice Cream Man'
p.itiz()
p.dump('/tmp/bob.json')

p2 = Player.load('/tmp/bob.json')
p2.itiz()
print(p.name + "is a " + p.occupation)

结果:

This iz bob
ur name is bob and ur lvl12
ur name is bob and ur lvl12
bob is a Ice Cream Man

注意,这个实现的作用就像“dict”不存在一样。构造函数接受单个的起始值,并且可以随意在对象上设置附加属性,这些属性也会被保存和还原

序列化:

{"name": "bob", "level": 12, "occupation": "Ice Cream Man"}

将二进制转换为ascii是很常见的,有几种不同的常用协议可以实现这一点。此示例执行base64编码。十六进制编码是另一种流行的选择。任何使用此文件的人都需要知道其编码。但它也需要知道它是一个python泡菜,所以没有太多额外的劳动力

import pickle
import binascii

class player :
    def __init__(self, name , level ):
        self.name = name
        self.level = level
    def itiz(self):
        print("ur name is {} and ur lvl{}".format(self.name,self.level))

p = player("bob",12)
with open("Player.txt","w") as fichierx:
    fichierx.write(binascii.b2a_base64(pickle.dumps(p)).decode('ascii'))

print(open("Player.txt").read())

相关问题 更多 >

    热门问题