gpt4 book ai didi

Python 序列化类并使用 JsonPickle 更改属性大小写

转载 作者:行者123 更新时间:2023-12-03 16:57:34 25 4
gpt4 key购买 nike

使用 Python 和 JsonPickle,如何使用特定的大小写(例如 Camel Case、Pascal 等)序列化对象?下面的答案是手动完成的,但是寻找特定的 Jsonpickle 解决方案,因为它可以处理复杂的对象类型。
JSON serialize a class and change property casing with Python
https://stackoverflow.com/a/8614096/15435022

class HardwareSystem:
def __init__(self, vm_size):
self.vm_size = vm_size
self.some_other_thing = 42
self.a = 'a'

def snake_to_camel(s):
a = s.split('_')
a[0] = a[0].lower()
if len(a) > 1:
a[1:] = [u.title() for u in a[1:]]
return ''.join(a)

def serialise(obj):
return {snake_to_camel(k): v for k, v in obj.__dict__.items()}

hp = HardwareSystem('Large')
print(json.dumps(serialise(hp), indent=4, default=serialise))

最佳答案

这是我的尝试。

from importlib import import_module
import inspect
import json
import jsonpickle
import re


def snake_to_camel(s):
a = s.split('_')
a[0] = a[0].lower()
if len(a) > 1:
a[1:] = [u.title() for u in a[1:]]
return ''.join(a)

def camel_to_snake(s):
snake = []
snake_len = len(s)
for idx, char in enumerate(s):
snake.append(char.lower())
if idx < snake_len - 1:
if char.islower() and s[idx+1].isupper():
snake.append('_')
return ''.join(snake)

def debug_output(obj):
output = '{}({})'
attrs = [attr + '=' + repr(getattr(obj, attr)) for attr in vars(obj)]
return output.format(obj.__class__.__name__, ', '.join(attrs))


class SoftwareSystem:
def __init__(self):
self.software_rating = 'Awesome!'

# Making debug output friendly
def __repr__(self):
return debug_output(self)


class HardwareSystem:
def __init__(self, vm_size):
self.vm_size = vm_size
self.some_other_thing = 42
self.a = 'a'

# Making debug output friendly
def __repr__(self):
return debug_output(self)


@jsonpickle.handlers.register(HardwareSystem, base=True)
@jsonpickle.handlers.register(SoftwareSystem, base=True)
class SystemHandler(jsonpickle.handlers.BaseHandler):
def flatten(self, obj, data):
for k, v in obj.__dict__.items():
data[snake_to_camel(k)] = jsonpickle.encode(v)
return data

def restore(self, obj):
# Gets reference to class
# https://stackoverflow.com/a/55559852/152016
module_path, class_name = obj['py/object'].rsplit('.', 1)
module = import_module(module_path)
class_ = getattr(module, class_name)

# Dealing with __init__ params (except first)
params = inspect.getargs(class_.__init__.__code__)
params = params.args[1:]

# Preparing dict keys
l_obj = {}
for k, v in obj.items():
l_obj[camel_to_snake(k)] = v

# Instantiating constructor params
data = {}
for k, v in l_obj.items():
if k in params:
data[k] = v
result = class_(**data)

# Setting other jsonpickled object attributes
for k, v in l_obj.items():
if not k in params:
setattr(result, k, v)

return result


hw = HardwareSystem(100)
sw = SoftwareSystem()
hw.software_instance = sw
json_str = jsonpickle.encode(hw)
print(json_str)
decoded = jsonpickle.decode(json_str)
print(hw)
这有一些假设:
  • 关注您的原创 snake_to_camel函数,我提出了一个 camel_to_snake在解码时,假设只有小写字母后的第一个大写字母将在 _ 前面加上字符(所以 awesomeABC 将转换为 awesome_abc ,而 因此,如果您再次将其转换回来,它将错误地为 awesomeAbc )
  • 上面的代码编码/解码在 __init__ 之后添加的属性(例如参见上面的 hw.software_instance)。
  • 您可以嵌套对象。我只试过一个嵌套的对象。
  • 我添加了辅助 debug_output/__repr__功能,你可以扔掉这些(或自定义:))
  • 关于Python 序列化类并使用 JsonPickle 更改属性大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66791380/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com