클래스 JSON을 시리얼화 하는 방법
Python 클래스를 직렬화하려면 어떻게 해야 합니까?
class FileItem:
def __init__(self, fname):
self.fname = fname
JSON에 직렬화 시도:
>>> import json
>>> x = FileItem('/foo/bar')
>>> json.dumps(x)
TypeError: Object of type 'FileItem' is not JSON serializable
다음은 간단한 기능을 위한 간단한 솔루션입니다.
.toJSON()
★★★
JSON serializable 클래스 대신 serializer 메서드를 구현합니다.
import json
class Object:
def toJSON(self):
return json.dumps(self, default=lambda o: o.__dict__,
sort_keys=True, indent=4)
시리얼라이즈라고 부르면 됩니다.
me = Object()
me.name = "Onur"
me.age = 35
me.dog = Object()
me.dog.name = "Apollo"
print(me.toJSON())
출력:
{
"age": 35,
"dog": {
"name": "Apollo"
},
"name": "Onur"
}
예상 생산량에 대해 알고 계십니까?예를 들어, 이것으로 충분할까요?
>>> f = FileItem("/foo/bar")
>>> magic(f)
'{"fname": "/foo/bar"}'
는 그냥 요.json.dumps(f.__dict__)
보다 커스터마이즈된 출력을 필요로 하는 경우는, 독자적인 커스텀 시리얼화를 서브 클래스 해 실장할 필요가 있습니다.
간단한 예에 대해서는, 이하를 참조해 주세요.
>>> from json import JSONEncoder
>>> class MyEncoder(JSONEncoder):
def default(self, o):
return o.__dict__
>>> MyEncoder().encode(f)
'{"fname": "/foo/bar"}'
그런 다음 이 클래스를 메서드에 전달합니다.cls
삭제:
json.dumps(cls=MyEncoder)
디코딩을 하려면 커스텀을 입력해야 합니다.object_hook
학급에.예를 들어 다음과 같습니다.
>>> def from_json(json_object):
if 'fname' in json_object:
return FileItem(json_object['fname'])
>>> f = JSONDecoder(object_hook = from_json).decode('{"fname": "/foo/bar"}')
>>> f
<__main__.FileItem object at 0x9337fac>
>>>
보다 복잡한 클래스의 경우 도구 jsonpickle을 고려할 수 있습니다.
jsonpickle은 JSON과 주고받는 복잡한 Python 객체를 직렬화 및 직렬화 해제하기 위한 Python 라이브러리입니다.
stdlib의 json, simplejson 및 demjson과 같이 Python을 JSON으로 인코딩하기 위한 표준 Python 라이브러리는 직접적인 JSON 상당(dicts, lists, string, int 등)을 가진 Python 프리미티브만 처리할 수 있습니다.json pickle은 이러한 라이브러리 위에 구축되어 JSon을 직렬화할 수 있습니다.ghly 설정 및 확장 가능 - 사용자가 JSON 백엔드를 선택하고 백엔드를 추가할 수 있습니다.
응답의 대부분은 콜을 json.dumps()로 변경하는 것입니다.이는 항상 가능하거나 바람직한 것은 아닙니다(예를 들어 프레임워크컴포넌트 내부에서 발생할 수 있습니다).
json.dumps(obj)를 그대로 호출할 수 있는 경우 간단한 솔루션이 dict에서 상속됩니다.
class FileItem(dict):
def __init__(self, fname):
dict.__init__(self, fname=fname)
f = FileItem('tasks.txt')
json.dumps(f) #No need to change anything here
이 기능은 클래스가 기본 데이터 표현일 경우 작동하며, 보다 까다로운 작업에는 항상 키를 명시적으로 설정할 수 있습니다.
했듯이, 여러분은 을 '하다'에게 수 있습니다.json.dumps
기본적으로 지원되지 않는 개체를 지원되는 유형으로 변환합니다.의외로 이들 중 가장 간단한 경우를 언급하는 것은 없습니다.즉, 빌트인 함수를 사용하여 객체를 모든 속성을 포함하는 딕트로 변환하는 것입니다.
json.dumps(obj, default=vars)
등 보다 , Atribute가는, 것에 해 주세요.__dict__
Atribute를 해야 .JSONEncoder
른른른
더하면 돼요.to_json
다음과 같은 방법으로 수업을 진행하십시오.
def to_json(self):
return self.message # or how you want it to be serialized
그리고 (이 답변에서) 이 코드를 모든 항목 맨 위에 추가합니다.
from json import JSONEncoder
def _default(self, obj):
return getattr(obj.__class__, "to_json", _default.default)(obj)
_default.default = JSONEncoder().default
JSONEncoder.default = _default
Import 됩니다.따라서 Import는 monkey-patch는 monkey-patch입니다.JSONEncoder.default()
는, 한 「」를 으로 합니다.to_json()
방법
오누르가 말한 것처럼, 하지만 이번엔 매번 업데이트 할 필요는 없어json.dumps()
를 참조해 주세요.
Onur의 답변은 마음에 들지만 옵션도 포함되도록 확장하겠습니다.toJSON()
「 」 「 」 、 「 」 、 「 」
def dumper(obj):
try:
return obj.toJSON()
except:
return obj.__dict__
print json.dumps(some_big_object, default=dumper, indent=2)
다른 옵션은 JSON 덤프를 자체 클래스로 랩하는 것입니다.
import json
class FileItem:
def __init__(self, fname):
self.fname = fname
def __repr__(self):
return json.dumps(self.__dict__)
파일 를 하위 분류하는 도 좋습니다.JsonSerializable
링크:
import json
class JsonSerializable(object):
def toJson(self):
return json.dumps(self.__dict__)
def __repr__(self):
return self.toJson()
class FileItem(JsonSerializable):
def __init__(self, fname):
self.fname = fname
테스트:
>>> f = FileItem('/foo/bar')
>>> f.toJson()
'{"fname": "/foo/bar"}'
>>> f
'{"fname": "/foo/bar"}'
>>> str(f) # string coercion
'{"fname": "/foo/bar"}'
Python 3.5+를 사용하고 있다면 를 사용할 수 있습니다.( PyPi : https://pypi.org/project/jsons/)오브젝트(및 오브젝트의 모든 속성)를 dict로 재귀적으로 변환합니다.
import jsons
a_dict = jsons.dump(your_object)
또는 문자열을 원하는 경우:
a_str = jsons.dumps(your_object)
당신의 클래스가 「」를 실장하고 있는 .jsons.JsonSerializable
:
a_dict = your_object.json
며칠 전에 이 문제를 발견하고 중첩된 개체와 상속된 필드를 처리할 수 있는 보다 일반적인 버전의 Python용 인코더 개체를 구현했습니다.
import json
import inspect
class ObjectEncoder(json.JSONEncoder):
def default(self, obj):
if hasattr(obj, "to_json"):
return self.default(obj.to_json())
elif hasattr(obj, "__dict__"):
d = dict(
(key, value)
for key, value in inspect.getmembers(obj)
if not key.startswith("__")
and not inspect.isabstract(value)
and not inspect.isbuiltin(value)
and not inspect.isfunction(value)
and not inspect.isgenerator(value)
and not inspect.isgeneratorfunction(value)
and not inspect.ismethod(value)
and not inspect.ismethoddescriptor(value)
and not inspect.isroutine(value)
)
return self.default(d)
return obj
예:
class C(object):
c = "NO"
def to_json(self):
return {"c": "YES"}
class B(object):
b = "B"
i = "I"
def __init__(self, y):
self.y = y
def f(self):
print "f"
class A(B):
a = "A"
def __init__(self):
self.b = [{"ab": B("y")}]
self.c = C()
print json.dumps(A(), cls=ObjectEncoder, indent=2, sort_keys=True)
결과:
{
"a": "A",
"b": [
{
"ab": {
"b": "B",
"i": "I",
"y": "y"
}
}
],
"c": {
"c": "YES"
},
"i": "I"
}
은 다음과 같습니다.
만들기json
work your 。
AKA, 결:json.dumps({ "thing": YOUR_CLASS() })
TLDR: 복사 붙여넣기 옵션1 또는 다음 옵션2
설명:
- 네, 신뢰할 수 있는 솔루션이 존재합니다.
- 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀, 비단뱀.
- 해결 방법이라고 (현재) 수 은 없습니다.
toJSON
JavaScript) / json json jon son java java java java java java java java java java java java java 。그런 일이 있을 때json.dumps([1,2, your_obj])
실행되면 python은 룩업 테이블이나 오브젝트 메서드를 체크하지 않습니다. - 왜 다른 답이 이걸 설명해주지 않는지 모르겠다.
- 가장 가까운 공식 접근법은 아마도 사전에서 물려받은 앤디하싯의 대답일 것이다.그러나 AdvancedDateTime 또는 pytorch 텐서와 같은 많은 사용자 지정 클래스에서는 사전에서 상속하는 것이 잘 작동하지 않습니다.
- 해결 방법이라고 (현재) 수 은 없습니다.
- 이상적인 회피책은 다음과 같습니다.
- " " "
json.dumps
을 미칩니다) (json "Import" pip "는 모든 곳에 영향을 줍니다) def __json__(self)
your class (
- " " "
옵션 1: 모듈에게 패치 적용 실행
pip install json-fix
(팬시존의 답변 확장판+패키지판, 감사합니다@FancyJohn)
your_class_definition.py
import json_fix
class YOUR_CLASS:
def __json__(self):
# YOUR CUSTOM CODE HERE
# you probably just want to do:
# return self.__dict__
return "a built-in object that is naturally json-able"
바로 그거야.
「 」:
from your_class_definition import YOUR_CLASS
import json
json.dumps([1,2, YOUR_CLASS()], indent=0)
# '[\n1,\n2,\n"a built-in object that is naturally json-able"\n]'
떻게게작?작 동??를를를 2 를를 。
★★★★★★★★★★★★★★★★★를 만들다json.dumps
Numpy 어레이, Panda DataFrames 및 기타 타사 개체에 대해서는 모듈을 참조하십시오(코드의 최대 2줄만 설명 필요).
옵션 2: json.dumps를 직접 패치합니다.
참고: 이 접근 방식은 단순하며 외부 클래스(numpy array, datetime, 데이터 프레임, 텐서 등)의 json 동작을 제어할 수 없습니다.
some_file_class_definitions_your_class_definitions.화이
# Step: 1
# create the patch
from json import JSONEncoder
def wrapped_default(self, obj):
return getattr(obj.__class__, "__json__", wrapped_default.default)(obj)
wrapped_default.default = JSONEncoder().default
# apply the patch
JSONEncoder.original_default = JSONEncoder.default
JSONEncoder.default = wrapped_default
your_class_definition을 지정합니다.화이
# Step 2
class YOUR_CLASS:
def __json__(self, **options):
# YOUR CUSTOM CODE HERE
# you probably just want to do:
# return self.__dict__
return "a built-in object that is natually json-able"
_
다른 답변은 모두 "커스텀 오브젝트를 시리얼화하기 위한 베스트 프랙티스/접근법"인 것 같습니다.
이는 문서(복잡한 번호의 인코딩 예에 대해서는 "복잡한" 검색)에서 이미 설명되어 있습니다.
import simplejson
class User(object):
def __init__(self, name, mail):
self.name = name
self.mail = mail
def _asdict(self):
return self.__dict__
print(simplejson.dumps(User('alice', 'alice@mail.com')))
'''를 json
을가 있습니다.default
import json
def default(o):
return o._asdict()
print(json.dumps(User('alice', 'alice@mail.com'), default=default))
json
가능한 오브젝트가 .jsonpickle
도 있습니다.pip install jsonpickle
수 이 있습니다는 텍스트를 들여쓸 수 없는 용어에 제한이 있습니다.클래스를 변경할 수 없는 객체의 내용을 검사하려면 다음 방법보다 더 정확한 방법을 찾을 수 없습니다.
import json
import jsonpickle
...
print json.dumps(json.loads(jsonpickle.encode(object)), indent=2)
주의: 여전히 오브젝트 메서드를 인쇄할 수 없습니다.
【3】
이는 트리와 같은 python 개체에 대한 명시적인 json 직렬화를 보여줍니다.
주의: 실제로 이와 같은 코드를 원하는 경우 트위스트 FilePath 클래스를 사용할 수 있습니다.
import json, sys, os
class File:
def __init__(self, path):
self.path = path
def isdir(self):
return os.path.isdir(self.path)
def isfile(self):
return os.path.isfile(self.path)
def children(self):
return [File(os.path.join(self.path, f))
for f in os.listdir(self.path)]
def getsize(self):
return os.path.getsize(self.path)
def getModificationTime(self):
return os.path.getmtime(self.path)
def _default(o):
d = {}
d['path'] = o.path
d['isFile'] = o.isfile()
d['isDir'] = o.isdir()
d['mtime'] = int(o.getModificationTime())
d['size'] = o.getsize() if o.isfile() else 0
if o.isdir(): d['children'] = o.children()
return d
folder = os.path.abspath('.')
json.dump(File(folder), sys.stdout, default=_default)
이 클래스는 오브젝트를 standard json으로 변환할 수 있습니다.
import json
class Serializer(object):
@staticmethod
def serialize(object):
return json.dumps(object, default=lambda o: o.__dict__.values()[0])
사용방법:
Serializer.serialize(my_object)
in in in 에서 일하다python2.7
★★★★★★★★★★★★★★★★★」python3
.
import json
class Foo(object):
def __init__(self):
self.bar = 'baz'
self._qux = 'flub'
def somemethod(self):
pass
def default(instance):
return {k: v
for k, v in vars(instance).items()
if not str(k).startswith('_')}
json_foo = json.dumps(Foo(), default=default)
assert '{"bar": "baz"}' == json_foo
print(json_foo)
jaraco는 꽤 깔끔한 대답을 했다.몇 가지 사소한 것들을 고쳐야 했지만, 이 방법은 효과가 있었다.
코드
# Your custom class
class MyCustom(object):
def __json__(self):
return {
'a': self.a,
'b': self.b,
'__python__': 'mymodule.submodule:MyCustom.from_json',
}
to_json = __json__ # supported by simplejson
@classmethod
def from_json(cls, json):
obj = cls()
obj.a = json['a']
obj.b = json['b']
return obj
# Dumping and loading
import simplejson
obj = MyCustom()
obj.a = 3
obj.b = 4
json = simplejson.dumps(obj, for_json=True)
# Two-step loading
obj2_dict = simplejson.loads(json)
obj2 = MyCustom.from_json(obj2_dict)
# Make sure we have the correct thing
assert isinstance(obj2, MyCustom)
assert obj2.__dict__ == obj.__dict__
로딩에는 2단계가 필요합니다.이제 금 으 for now는,서?__python__
속성이 사용되지 않습니다.속성은 사용되지 않습니다.
얼마나 흔한 일인가요?
AlJohri 방법을 사용하여 접근법의 인기를 확인합니다.
시리얼화(Python -> JSON):
to_json
: 2018년 6월 27일 266,595toJSON
: 2018년 6월 27일 96,307명__json__
: 2018-06-27 8,504for_json
: 2018-06-27 6,937
역직렬화(JSON -> Python):
from_json
: 2018-06-27의 경우 226,101
이것은 나에게 있어서 좋은 결과입니다.
class JsonSerializable(object):
def serialize(self):
return json.dumps(self.__dict__)
def __repr__(self):
return self.serialize()
@staticmethod
def dumper(obj):
if "serialize" in dir(obj):
return obj.serialize()
return obj.__dict__
그리고 나서.
class FileItem(JsonSerializable):
...
그리고.
log.debug(json.dumps(<my object>, default=JsonSerializable.dumper, indent=2))
패키지의 인스톨에 문제가 없는 경우는, 다음의 json-tricks 를 사용할 수 있습니다.
pip install json-tricks
import 그 가져오기 면 가져오기 니 다 됩)를 가져오셔야 합니다.dump(s)
부에서json_tricks
json 대신에, 보통 일을 할 것입니다.보통 효과가 있습니다.
from json_tricks import dumps
json_str = dumps(cls_instance, indent=4)
그렇게 되면
{
"__instance_type__": [
"module_name.test_class",
"MyTestCls"
],
"attributes": {
"attr": "val",
"dct_attr": {
"hello": 42
}
}
}
그게 다예요!
이것은 일반적으로 매우 효과적일 것입니다. 가지 예외가. 이 일어나면요. 예를 들어, 에서 특별한 일이 발생할 수 있습니다.__new__
로딩도 확실히 기능합니다(그렇지 않으면 의미가 없습니다).
from json_tricks import loads
json_str = loads(json_str)
은 '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아'라고 가정합니다.module_name.test_class.MyTestCls
가져올 수 있으며 호환되지 않는 방식으로 변경되지 않았습니다.어떤 사전 같은 게 아니라 인스턴스 하나를 돌려받을 거고, 당신이 버린 것과 똑같은 복사본이어야 해요.
연속화(비연속화) 방법을 사용자 정의하려면 다음과 같이 클래스에 특수 메서드를 추가할 수 있습니다.
class CustomEncodeCls:
def __init__(self):
self.relevant = 42
self.irrelevant = 37
def __json_encode__(self):
# should return primitive, serializable types like dict, list, int, string, float...
return {'relevant': self.relevant}
def __json_decode__(self, **attrs):
# should initialize all properties; note that __init__ is not called implicitly
self.relevant = attrs['relevant']
self.irrelevant = 12
예를 들어 Atribut 파라미터의 일부만 시리얼화합니다.
또한 무료 보너스로 numpy 어레이, 날짜 및 시간, 주문된 맵의 시리얼화 및 json에 코멘트를 포함할 수 있습니다.
면책사항:당신과 같은 문제가 있었기 때문에 json_tricks를 만들었습니다.
Kyle Delaney의 코멘트가 정확하기 때문에 https://stackoverflow.com/a/15538391/1497139과 https://stackoverflow.com/a/10254820/1497139의 개량판을 사용하려고 했습니다.
'JSONAble' 믹스인을 만듭니다.
클래스 JSON을 시리얼라이즈 할 수 있도록 하려면 , 「JSONABLE」을 슈퍼 클래스로 사용해, 다음의 어느쪽인가를 호출합니다.
instance.toJSON()
또는
instance.asJSON()
두 가지 방법이 있습니다.JSONAble 클래스를 여기서 제공하는 다른 접근법으로 확장할 수도 있습니다.
가족 및 인물을 사용한 단위 테스트 샘플의 검정 예제는 다음과 같습니다.
toJSOn():
{
"members": {
"Flintstone,Fred": {
"firstName": "Fred",
"lastName": "Flintstone"
},
"Flintstone,Wilma": {
"firstName": "Wilma",
"lastName": "Flintstone"
}
},
"name": "The Flintstones"
}
asJSOn():
{'name': 'The Flintstones', 'members': {'Flintstone,Fred': {'firstName': 'Fred', 'lastName': 'Flintstone'}, 'Flintstone,Wilma': {'firstName': 'Wilma', 'lastName': 'Flintstone'}}}
가족 및 개인 샘플에 의한 단위 테스트
def testJsonAble(self):
family=Family("The Flintstones")
family.add(Person("Fred","Flintstone"))
family.add(Person("Wilma","Flintstone"))
json1=family.toJSON()
json2=family.asJSON()
print(json1)
print(json2)
class Family(JSONAble):
def __init__(self,name):
self.name=name
self.members={}
def add(self,person):
self.members[person.lastName+","+person.firstName]=person
class Person(JSONAble):
def __init__(self,firstName,lastName):
self.firstName=firstName;
self.lastName=lastName;
jsonable.py 정의 JSONAble 믹스인
'''
Created on 2020-09-03
@author: wf
'''
import json
class JSONAble(object):
'''
mixin to allow classes to be JSON serializable see
https://stackoverflow.com/questions/3768895/how-to-make-a-class-json-serializable
'''
def __init__(self):
'''
Constructor
'''
def toJSON(self):
return json.dumps(self, default=lambda o: o.__dict__,
sort_keys=True, indent=4)
def getValue(self,v):
if (hasattr(v, "asJSON")):
return v.asJSON()
elif type(v) is dict:
return self.reprDict(v)
elif type(v) is list:
vlist=[]
for vitem in v:
vlist.append(self.getValue(vitem))
return vlist
else:
return v
def reprDict(self,srcDict):
'''
get my dict elements
'''
d = dict()
for a, v in srcDict.items():
d[a]=self.getValue(v)
return d
def asJSON(self):
'''
recursively return my dict elements
'''
return self.reprDict(self.__dict__)
이러한 접근방식은 https://pypi.org/project/pylodstorage/에서 이용할 수 있는 https://github.com/WolfgangFahl/pyLoDStorage 프로젝트에 통합되었습니다.
jsonweb이 저에게 가장 좋은 솔루션인 것 같습니다.http://www.jsonweb.info/en/latest/ 를 참조해 주세요.
from jsonweb.encode import to_object, dumper
@to_object()
class DataModel(object):
def __init__(self, id, value):
self.id = id
self.value = value
>>> data = DataModel(5, "foo")
>>> dumper(data)
'{"__type__": "DataModel", "id": 5, "value": "foo"}'
class DObject(json.JSONEncoder):
def delete_not_related_keys(self, _dict):
for key in ["skipkeys", "ensure_ascii", "check_circular", "allow_nan", "sort_keys", "indent"]:
try:
del _dict[key]
except:
continue
def default(self, o):
if hasattr(o, '__dict__'):
my_dict = o.__dict__.copy()
self.delete_not_related_keys(my_dict)
return my_dict
else:
return o
a = DObject()
a.name = 'abdul wahid'
b = DObject()
b.name = a
print(json.dumps(b, cls=DObject))
def sterilize(obj):
"""Make an object more ameniable to dumping as json
"""
if type(obj) in (str, float, int, bool, type(None)):
return obj
elif isinstance(obj, dict):
return {k: sterilize(v) for k, v in obj.items()}
list_ret = []
dict_ret = {}
for a in dir(obj):
if a == '__iter__' and callable(obj.__iter__):
list_ret.extend([sterilize(v) for v in obj])
elif a == '__dict__':
dict_ret.update({k: sterilize(v) for k, v in obj.__dict__.items() if k not in ['__module__', '__dict__', '__weakref__', '__doc__']})
elif a not in ['__doc__', '__module__']:
aval = getattr(obj, a)
if type(aval) in (str, float, int, bool, type(None)):
dict_ret[a] = aval
elif a != '__class__' and a != '__objclass__' and isinstance(aval, type):
dict_ret[a] = sterilize(aval)
if len(list_ret) == 0:
if len(dict_ret) == 0:
return repr(obj)
return dict_ret
else:
if len(dict_ret) == 0:
return list_ret
return (list_ret, dict_ret)
차이점은
- '반복'이 아니라 '이 가능한 모든 경우에 따라서는 동작합니다.
list
★★★★★★★★★★★★★★★★★」tuple
(NumPy ★★★★★★★★★★★) - 유형 유형(동적 유형( 유형)(동적 유형 ))에 대해 합니다.
__dict__
를 참조해 주세요. - 타입 「」을 포함합니다.
float
★★★★★★★★★★★★★★★★★」None
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ - 「」가 있는
__dict__
멤버는 주로 일을 합니다(만약__dict__
멤버명이 충돌하면1개밖에 표시되지 않습니다(멤버일 가능성이 높습니다). - 리스트이며 멤버가 있는 클래스는 리스트와 사전의 태플처럼 보입니다.
- 그 Python3 (그)))
isinstance()
변경할 필요가 있는 것은 전화뿐일 수 있습니다.)
이 11년 된 화재에 또 다른 통나무를 던지려면 다음 기준을 충족하는 솔루션을 원합니다.
- 를 FileItem만 할 수 .
json.dumps(obj)
- FileItem 인스턴스에 fileItem 속성을 지정할 수 있습니다.이름
- 을 사용하여 에 지정할 수 .
json.dumps(obj)
- 됩니다.
json.dumps
처럼) ('커스텀시리얼라이저처럼)
IE:
fileItem = FileItem('filename.ext')
assert json.dumps(fileItem) == '{"fname": "filename.ext"}'
assert fileItem.fname == 'filename.ext'
솔루션은 다음과 같습니다.
- 을 obj에게 .
dict
- .
dict
class FileItem(dict):
def __init__(self, fname):
self['fname'] = fname
#fname property
fname: str = property()
@fname.getter
def fname(self):
return self['fname']
@fname.setter
def fname(self, value: str):
self['fname'] = value
#Repeat for other properties
네, 많은 속성이 있는 경우에는 다소 긴 감기가 있지만 JSON Serializable이 가능하며 오브젝트처럼 동작합니다.이것에 의해, 어느 라이브러리에도 액세스 할 수 있습니다.json.dumps(obj)
바로 그거에요.
왜 이렇게 복잡하게 만드세요?다음으로 간단한 예를 제시하겠습니다.
#!/usr/bin/env python3
import json
from dataclasses import dataclass
@dataclass
class Person:
first: str
last: str
age: int
@property
def __json__(self):
return {
"name": f"{self.first} {self.last}",
"age": self.age
}
john = Person("John", "Doe", 42)
print(json.dumps(john, indent=4, default=lambda x: x.__json__))
클래스를 .__json__
비단뱀 no no no 、 no 、 no 、 no 、 no 、 no 、 no no no 。JSONEncoder
,default
단순 람다를 사용하는 매개 변수도 올바르게 작동합니다.
가 쓴 적이 있어요.@property
단순한 기능보다는 좀 더 자연스럽고 모던한 느낌이에요.@dataclass
에서도 사용할 수, 수, 예, 예, 예,예, 예, 예, '보통' 클래스에서도 할 수 .
나는 로스트 코더의 방식이 가장 마음에 들었다.멤버/메서드를 직렬화할 수 없는 더 복잡한 개체를 직렬화할 때 문제가 발생했습니다.다음은 더 많은 개체에서 작동하는 구현입니다.
class Serializer(object):
@staticmethod
def serialize(obj):
def check(o):
for k, v in o.__dict__.items():
try:
_ = json.dumps(v)
o.__dict__[k] = v
except TypeError:
o.__dict__[k] = str(v)
return o
return json.dumps(check(obj).__dict__, indent=2)
Peee pe 、 Postgre pe 、 Postgre pe pe pe pe pe 。SQLJSONField
.
한동안 고군분투한 끝에 일반적인 해결책이 여기 있습니다.
내 솔루션의 핵심은 Python의 소스 코드를 살펴보고 코드 문서(여기 설명됨)가 기존 코드를 확장하는 방법을 이미 설명한다는 것을 깨닫는 것입니다.json.dumps
하다
현재 JSON에 대해 직렬화할 수 없는 일부 필드를 포함하는 모델이 있고 JSON 필드를 포함하는 모델은 원래 다음과 같습니다.
class SomeClass(Model):
json_field = JSONField()
커스텀을 .JSONEncoder
음음음같 뭇매하다
class CustomJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, SomeTypeUnsupportedByJsonDumps):
return < whatever value you want >
return json.JSONEncoder.default(self, obj)
@staticmethod
def json_dumper(obj):
return json.dumps(obj, cls=CustomJsonEncoder)
에 그냥 '아예'에요.JSONField
음음음같 뭇매하다
class SomeClass(Model):
json_field = JSONField(dumps=CustomJsonEncoder.json_dumper)
는 「」입니다.default(self, obj)
★★★★★★★마다 1★★★★★... is not JSON serializable
Python에서 불만 Python 등을하는 코드를 하는 것 입니다.Enum
★★★★★★★★★★★★★★★★★」datetime
)
예를 들어, 다음에서 상속되는 클래스를 지원하는 방법은 다음과 같습니다.Enum
:
class TransactionType(Enum):
CURRENT = 1
STACKED = 2
def default(self, obj):
if isinstance(obj, TransactionType):
return obj.value
return json.JSONEncoder.default(self, obj)
마지막으로 위와 같이 구현된 코드를 사용하여 Peeee 모델을 다음과 같이 JSON-seriazable 객체로 변환할 수 있습니다.
peewee_model = WhateverPeeweeModel()
new_model = SomeClass()
new_model.json_field = model_to_dict(peewee_model)
위의 코드는 Peeee에게만 해당되는 것이지만, 저는 다음과 같이 생각합니다.
- 일반적으로 다른 ORM(장고 등)에 적용할 수 있습니다.
- 어떻게 아는지 알 수 있어요.
json.dumps
Python ORM합니다.
질문 있으시면 댓글로 올려주세요.감사합니다!
먼저 표준 JSON 모듈을 사용하여 덤프할 수 있도록 객체를 JSON에 준거해야 합니다.나는 이렇게 했다:
def serialize(o):
if isinstance(o, dict):
return {k:serialize(v) for k,v in o.items()}
if isinstance(o, list):
return [serialize(e) for e in o]
if isinstance(o, bytes):
return o.decode("utf-8")
return o
이 함수는 재귀를 사용하여 사전의 모든 부분에 걸쳐 반복한 후 빌트인 유형이 아닌 클래스의 repr() 메서드를 호출합니다.
def sterilize(obj):
object_type = type(obj)
if isinstance(obj, dict):
return {k: sterilize(v) for k, v in obj.items()}
elif object_type in (list, tuple):
return [sterilize(v) for v in obj]
elif object_type in (str, int, bool, float):
return obj
else:
return obj.__repr__()
나는 나만의 해결책을 생각해 냈다.이 방법을 사용하여 일련화할 문서(dict, list, ObjectId 등)를 전달합니다.
def getSerializable(doc):
# check if it's a list
if isinstance(doc, list):
for i, val in enumerate(doc):
doc[i] = getSerializable(doc[i])
return doc
# check if it's a dict
if isinstance(doc, dict):
for key in doc.keys():
doc[key] = getSerializable(doc[key])
return doc
# Process ObjectId
if isinstance(doc, ObjectId):
doc = str(doc)
return doc
# Use any other custom serializting stuff here...
# For the rest of stuff
return doc
언급URL : https://stackoverflow.com/questions/3768895/how-to-make-a-class-json-serializable
'source' 카테고리의 다른 글
어떻게 두 줄을 숫자처럼 추가할 수 있죠? (0) | 2022.12.25 |
---|---|
HTML 파일의 JavaScript 위치 (0) | 2022.12.25 |
읽기 전용 목록 또는 수정 가능한 목록을 읽습니다.Net4.0 (0) | 2022.12.25 |
"서브쿼리가 두 개 이상의 행을 반환함" 오류 해결 방법 (0) | 2022.12.25 |
webpack-dev-server에 원격으로 연결하면 "Invalid Host header" 메시지가 나타난다. (0) | 2022.12.25 |