You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

66 lines
2.1 KiB

from inspect import signature, Parameter
from functools import wraps
from typing import Optional
import re
CAMEL_REGEX = re.compile(r'([A-Z])')
UNDERSCORE_REGEX = re.compile(r'_([a-z])')
def camel_to_underscore(name):
return CAMEL_REGEX.sub(lambda x: '_' + x.group(1).lower(), name)
def underscore_to_camel(name):
return UNDERSCORE_REGEX.sub(lambda x: x.group(1).upper(), name)
def is_field_private(field_name: str) -> Optional[str]:
m = re.match(r'_[^(__)]+__', field_name)
return m is not None
def inited_params(target_init):
target_params = signature(target_init).parameters.values()
if len(target_params) < 1:
raise ValueError('init function mush have at least self parameter')
if len(target_params) == 1:
return target_init
_, *target_params = target_params # we will not use self any more
@wraps(target_init)
def wrapped_init(wrapped_self, *wrapped_args, **wrapped_kwargs):
for tp in target_params:
if tp.default is Parameter.empty:
continue
setattr(wrapped_self, tp.name, tp.default)
for tp, v in zip(target_params, wrapped_args):
setattr(wrapped_self, tp.name, v)
for k, v in wrapped_kwargs.items():
setattr(wrapped_self, k, v)
target_init(wrapped_self, *wrapped_args, **wrapped_kwargs)
return wrapped_init
def JSONClass(target_class):
def to_json(self) -> dict:
"""
returns a json representation of the class
where all None - values and private fileds are skipped
"""
return {
underscore_to_camel(k): v for k, v in self.__dict__.items()
if v is not None and not is_field_private(k)
}
def from_json(json_object: Optional[dict]) -> target_class:
if json_object is None:
json_object = {}
init_object = { camel_to_underscore(k): v for k, v in json_object.items() }
return target_class(**init_object)
# target_class.__init__ = inited_params(target_class.__init__)
target_class.to_json = to_json
target_class.from_json = from_json
return target_class