如何使Python类可序列化?
一个简单的课程:
class FileItem:
def __init__(self, fname):
self.fname = fname
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能得到输出:
>>> import json
>>> my_file = FileItem('/foo/bar')
>>> json.dumps(my_file)
TypeError: Object of type 'FileItem' is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
没有错误(__CODE__)
我有一个基本的词典如下:
sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere
Run Code Online (Sandbox Code Playgroud)
当我尝试做的时候,jsonify(sample)我得到:
TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable
我能做些什么,以便我的字典样本可以克服上述错误?
注意:虽然它可能不相关,但字典是从mongodb中检索记录生成的,当我打印输出时str(sample['somedate']),输出是2012-08-08 21:46:24.862000.
我想了解什么是猴子补丁或猴子补丁?
这类似于方法/运算符重载或委托吗?
这些东西有什么共同之处吗?
我有一个set包含对象__hash__和__eq__方法的Python ,以确保集合中不包含任何重复项.
我需要对这个结果进行json编码set,但是将一个空值传递set给该json.dumps方法会引发一个问题TypeError.
File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 178, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: set([]) is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
我知道我可以创建一个json.JSONEncoder具有自定义default方法的类的扩展,但我甚至不确定从哪里开始转换set.我应该set使用默认方法中的值创建字典,然后返回编码吗?理想情况下,我想使默认方法能够处理原始编码器所扼杀的所有数据类型(我使用Mongo作为数据源,所以日期似乎也引发了这个错误)
任何暗示正确的方向将不胜感激.
编辑:
谢谢你的回答!也许我应该更精确.
我在这里使用(和upvoted)答案来解决set被翻译的限制,但是内部键也是一个问题.
这些对象set是转换为的复杂对象__dict__,但它们本身也可以包含其属性的值,这些值可能不适用于json编码器中的基本类型.
这里有很多不同的类型set,哈希基本上计算了实体的唯一ID,但是在NoSQL的真正精神中,没有确切知道子对象包含的内容.
一个对象可能包含日期值 …
我想计算一个不是字符串的md5哈希,而是计算整个数据结构.我理解一种方法的机制(对值的类型进行调度,规范化字典键顺序和其他随机性,递归到子值等).但这似乎是一种通常有用的操作,所以我很惊讶我需要自己动手.
在Python中有一些更简单的方法来实现这一目标吗?
更新:pickle已被建议,这是一个好主意,但酸洗不规范字典键顺序:
>>> import cPickle as pickle
>>> import hashlib, random
>>> for i in range(10):
... k = [i*i for i in range(1000)]
... random.shuffle(k)
... d = dict.fromkeys(k, 1)
... p = pickle.dumps(d)
... print hashlib.md5(p).hexdigest()
...
51b5855799f6d574c722ef9e50c2622b
43d6b52b885f4ecb4b4be7ecdcfbb04e
e7be0e6d923fe1b30c6fbd5dcd3c20b9
aebb2298be19908e523e86a3f3712207
7db3fe10dcdb70652f845b02b6557061
43945441efe82483ba65fda471d79254
8e4196468769333d170b6bb179b4aee0
951446fa44dba9a1a26e7df9083dcadf
06b09465917d3881707a4909f67451ae
386e3f08a3c1156edd1bd0f3862df481
Run Code Online (Sandbox Code Playgroud) 鉴于下面的代码示例,如何使用Python 3使用JSON序列化这些类实例?
class TreeNode():
def __init__(self, name):
self.name = name
self.children = []
Run Code Online (Sandbox Code Playgroud)
当我尝试做一个时,json.dumps我收到以下错误:
TypeError: <TreeNode object at 0x7f6sf4276f60> is not JSON serializable
然后我才能发现,如果我将默认值设置json.dumps为返回,__dict__我可以将其序列化很好,但后来做了json.loads一个问题.
我可以找到许多带有基本字符串的自定义编码器/解码器示例,但是没有列表,在这种情况下是self.children.子列表将保存子节点及其子节点的其他节点.我需要一种方法来获得所有这些.
我可以通过以下示例总结我的问题:
from enum import Enum
import json
class FooBarType(Enum):
standard = 0
foo = 1
bar = 2
dict = {'name': 'test', 'value': 'test', 'type': FooBarType.foo}
json.dumps(dict)
TypeError: <FooBarType.foo: 1> is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
我收到类型错误,因为枚举不是JSON可序列化的.
我主要是实现a JsonEncoder并将其添加到json.dumps()调用中但我无法更改json.dumps()调用的行.
所以,我的问题是:
是否可以在不通过编码器的情况下在json中转储枚举json.dumps(),而是通过在FooBarType枚举中添加类方法?
我希望提取以下json:
{'name': 'test', 'value': 'test', 'type': 'foo'}
Run Code Online (Sandbox Code Playgroud)
要么
{'name': 'test', 'value': 'test', 'type': 1}
Run Code Online (Sandbox Code Playgroud) 我有一些二进制数据,在 Python 中以字节字符串数组的形式存在。
是否有一种可移植的方法来序列化其他语言可以读取的数据?
JSON 失败是因为我刚刚发现它没有真正的方法来存储二进制数据;它的字符串应该是 Unicode。
我不想使用,pickle因为我不想承担安全风险,这限制了它在其他 Python 程序中的使用。
有什么建议吗?我真的很想使用一个内置库(或者至少是标准 Anaconda 发行版的一部分)。
我需要一种有效的方法来编写包含字典(包括日期时间)的文件,然后能够将它们作为字典读取。像这样的字典:
my_dict = {'1.0': [datetime.datetime(2000, 1, 1, 0, 0, 0, 000000, tzinfo=tzutc())], '2.0': [datetime.datetime(2000, 1, 1, 0, 0, 0, 000000, tzinfo=tzutc())]}
Run Code Online (Sandbox Code Playgroud)
尝试使用 json 转储:
with open("my_file.json", 'w+') as f:
json.dump(my_dict, f)
Run Code Online (Sandbox Code Playgroud)
TypeError: Object of type 'datetime' is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
还尝试将整个 dict 写为一个字符串,然后用 yaml 导入它,这几乎有效,但索引混乱。
with open("my_file", 'w+') as f:
f.write(str(my_dict))
with open("my_file", 'r') as f:
s = f.read()
new_dict = yaml.load(s)
print(new_dict['1.0'][0])
Run Code Online (Sandbox Code Playgroud)
Output: datetime.datetime(2000
Expected: 2000-01-01 00:00:00+00:00
Run Code Online (Sandbox Code Playgroud) 我无法转储collections.namedtuple为正确的 JSON。
首先,考虑使用自定义 JSON 序列化程序的官方示例:
import json
class ComplexEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, complex):
return [obj.real, obj.imag]
# Let the base class default method raise the TypeError
return json.JSONEncoder.default(self, obj)
json.dumps(2 + 1j, cls=ComplexEncoder) # works great, without a doubt
Run Code Online (Sandbox Code Playgroud)
其次,现在考虑以下示例,它告诉 Python 如何对Friend对象进行 JSONize:
import json
class Friend():
""" struct-like, for storing state details of a friend """
def __init__(self, _id, f_name, l_name):
self._id = _id
self.f_name = f_name
self.l_name = …Run Code Online (Sandbox Code Playgroud) 我写了一个类,允许我将天数(整数)添加到日期(字符串 %Y-%m-%d)。这个类的对象需要是 JSON 可序列化的。
以整数形式向我的对象添加天数按预期工作。但是 json.dumps(obj) 为我的原始对象返回了太多信息(“2016-03-23 15:57:47.926362”)。为什么 ?我需要如何修改类以获取“2016-03-23”?请参见下面的示例。
代码:
from datetime import datetime, timedelta
import json
class Day(str):
def __init__(self, _datetime):
self.day = _datetime
def __str__(self):
return self.day.date().isoformat()
def __repr__(self):
return "%s" % self.day.date().isoformat()
def __add__(self, day):
new_day = self.day + timedelta(days=day)
return Day(new_day).__str__()
def __sub__(self, day):
new_day = self.day - timedelta(days=day)
return Day(new_day).__str__()
if __name__ == "__main__":
today = Day(datetime.today())
print(today) # 2016-03-23
print(json.dumps(today)) # "2016-03-23 15:57:47.926362"
print(today+1) # 2016-03-24
print(json.dumps(today+1)) # "2016-03-24"
print(today-1) # 2016-03-22 …Run Code Online (Sandbox Code Playgroud) python ×11
json ×8
datetime ×2
python-2.7 ×2
binary ×1
class ×1
dictionary ×1
enums ×1
eval ×1
md5 ×1
python-3.5 ×1
python-3.x ×1
set ×1
terminology ×1