基于ast.literal评估的序列化

serpent的Python项目详细描述


serpent是一个基于ast.literal评估的简单序列化库。

因为它只序列化文本并使用ast.literal_eval()重新创建对象, 序列化的数据可以安全地传输到其他计算机(例如通过网络) 然后反序列化。

还有一个java和一个.net(c)实现。这使得各种生态系统之间的数据传输变得容易。 您可以获得完整的源代码发行版、java.jar文件和.net程序集dll。 可以从maven central(groupidnet.razorvineartifactidserpent)获取java库, .net程序集可以从nuget.org(packageRazorvine.Serpent)获得。

api

  • ser_bytes = serpent.dumps(obj, indent=False, set_literals=True, module_in_classname=False):将obj树序列化为字节
  • obj = serpent.loads(ser_bytes)将字节反序列化回对象树
  • 您可以使用ast.literal_eval自己反序列化,但是serpent.deserialize 在一些角落的案子里工作。有关详细信息,请参见来源。

蛇比简单的repr()+literal_eval()复杂得多:

  • 它直接序列化为字节(utf-8编码),而不是字符串,因此可以立即将其保存到文件或通过套接字发送
  • 它将字节类型编码为base-64,而不是repr将使用的低效转义表示法(这意味着 在接收端手动对这些字符串进行base-64解码以获取字节。 您可以为此使用serpent.tobytes实用程序功能。)
  • 它包含一些用于其他几种python类型的自定义序列化程序,如uuid、datetime、array和decimal
  • 它尝试将无法识别的类型序列化为dict(您可以使用自己的类型上的getstate来控制此操作)
  • 它可以为可读性创建漂亮的打印(缩进)输出
  • 它按字母顺序输出集合和听写的键(打印时)
  • 它解决了各种python实现中ast.literal_eval()的一些怪癖

serpent允许在序列化数据中添加注释(因为它只是python源代码)。 serpent无法序列化对象图(当对象引用自身时);它将崩溃,并出现一个值错误,指出问题所在。

适用于Python2.7+(包括3.x)、IronPython2.7+、Jython2.7+。

faq

  • 为什么不使用xml呢?答:因为XML。
  • 为什么不使用json?答:因为json支持的数据类型数量非常有限,而且不能在json文件中使用注释。
  • 为什么不用泡菜呢?答:因为pickle有安全问题。
  • 为什么不使用repr()/ast.literal_eval()?见上图;蛇是这个的超集,提供了更多的便利。 serpent为内置基元类型以外的类型提供自动序列化映射。 repr()无法将这些序列化为ast.literal_eval()可以理解的文本。
  • 为什么不是二进制格式?答:因为人类无法读取二进制文件。
  • 但我不在乎可读性。答:没关系,ast.literal_eval()需要一个文本字符串,所以这就是我们要生成的。
  • 但我想要更好的表现。答:好吧,也许在这种情况下你不应该使用蛇。找到一个有效的二进制协议(protobuf?)
  • 为什么只有python、java和c/.net,而没有用于在此处插入喜爱的语言的绑定?答:我不会说那种语言。 也许你可以自己移植蛇?
  • 源头在哪里?在github上:https://github.com/irmen/Serpent
  • 我能到处用吗?当然,只要你保留版权和免责声明。请参阅许可证文件。

demo

# This demo script is written for Python 3.2+# -*- coding: utf-8 -*-from__future__importprint_functionimportastimportuuidimportdatetimeimportpprintimportserpentclassDemoClass:def__init__(self):self.i=42self.b=Falsedata={"names":["Harry","Sally","Peter"],"big":2**200,"colorset":{"red","green"},"id":uuid.uuid4(),"timestamp":datetime.datetime.now(),"class":DemoClass(),"unicode":"€"}# serialize itser=serpent.dumps(data,indent=True)open("data.serpent","wb").write(ser)print("Serialized form:")print(ser.decode("utf-8"))# read it backdata=serpent.load(open("data.serpent","rb"))print("Data:")pprint.pprint(data)# you can also use ast.literal_eval if you likeser_string=open("data.serpent","r",encoding="utf-8").read()data2=ast.literal_eval(ser_string)assertdata2==data

当您运行此程序(使用Python3.2+)时,它会打印:

Serializedform:# serpent utf-8 python3.2{'big':1606938044258990275541962092341162602522202993782792835301376,'class':{'__class__':'DemoClass','b':False,'i':42},'colorset':{'green','red'},'id':'e461378a-201d-4844-8119-7c1570d9d186','names':['Harry','Sally','Peter'],'timestamp':'2013-04-02T00:23:00.924000','unicode':'€'}Data:{'big':1606938044258990275541962092341162602522202993782792835301376,'class':{'__class__':'DemoClass','b':False,'i':42},'colorset':{'green','red'},'id':'e461378a-201d-4844-8119-7c1570d9d186','names':['Harry','Sally','Peter'],'timestamp':'2013-04-02T00:23:00.924000','unicode':'€'}

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
JavaFX进度条从单独的函数更改而来   jvm使用java服务器选项   java在<li>元素中查找同名的最后一个链接   java问题将参数传递给不同公共类中的构造函数   如何在php中从java函数中获取字符串   java如何在Android中动态显示多个tile   java仅使用Ribbon而不使用任何服务注册表是否可以实现负载平衡?   Jersey 1.19版本的java Swagger JAXRS出现“冲突URI模板”错误   带H2数据库的java Spring boot jpa   从12:00:00到00:00:00的日期转换   Android中的java如何设置文本?   java密钥库“不支持的保护参数”   http使用Java在Java中发送httprequest。净包   SpringJava刷新数据库   java在Spring Boot应用程序中使用嵌入式MongoDb和MongoTemplate失败   java需要什么MatOfMatch对象?   xml使用Java中的合并算法将两个值合并为单个值   java SQLite数据库不保存数据为什么不工作