Skip to main content

convert a primitive dict-list data structure to/from an instance of user-defined class.

Project description

object converter from primitive and to primitive

Origins

Python being a dynamically typed language, developers are not in the habit of defining types for their data. This is flexible, but not convenient enough when dealing with complex business logic - the lack of type checking can make it hard to find errors, and there are no code hints when coding in the IDE. So this tool was developed to fix it.

Usage-basic

  • First define the business class and define the type of each field through class variables.
from typing import List


class Person:
    name: str
    age: int


class Company:
    name: str
    revenue: float
    employees: List[Person]

The reason why class variables are chosen for definition is that it is the most concise and intuitive. In contrast, there is no way to get the type definition (type_hint) if you initialize the instance variable in the init method, and it is obviously more complicated if you use the @property annotation or getter, setter methods. They are not as simple and elegant as defining class variables directly. But there is a downside to using class variables: it is used here as metadata, and if you really need to define variables shared at the class level, it is impossible to distinguish them. This problem can be solved later by developing custom annotations.

  • The next step is to transform the dict-list nested data, which matches the structure of this class definition, into an instance object of the class.
from objtyping import objtyping

company1 = objtyping.from_primitive({
    'name': 'Apple',
    'revenue': 18.5,
    'employees': [{
        'name': 'Tom',
        'age': 20
    }, {
        'name': 'Jerry',
        'age': 31
    }]
}, Company)

Now company1 is a complete Company object, and you can directly access the properties in it in the form of company1.name, company1.employees[0].name, etc.

  • Of course, you can also turn the business object back into a dict-list nested form
from objtyping import objtyping

dict_list = objtyping.to_primitive(company1)

The primitve object, at this point, is a large pile of primitive type data nested at the dict and list levels

Scenes

Initializing an object

Python does not have as convenient a way to initialize objects as js, but with this tool it can be written like this (which is the summary of the previous basic use).

from typing import List

from objtyping import objtyping


class Person:
    name: str
    age: int


class Company:
    name: str
    revenue: float
    employees: List[Person]

    def __str__(self):  
        return "'{}' has {} employees: {}".format(self.name, len(self.employees), ' and '.join(map(lambda emp: emp.name, self.employees)))


if __name__ == '__main__':
    company1 = objtyping.from_primitive({
        'name': 'Apple',
        'revenue': 18.5,
        'employees': [{
            'name': 'Tom',
            'age': 20
        }, {
            'name': 'Jerry',
            'age': 31
        }]
    }, Company)

    print(company1)

output:

'Apple' has 2 employees: Tom and Jerry

serialization / deserialization

Python's common serialization requirements, including the json and yaml data formats, have relatively well-developed libraries for handling them. But again, because of the lack of emphasis on types, they handle objects in raw primitive format. It is just right to use this tool to achieve further conversion.

json

demo

import json
import sys
from typing import List

from objtyping import objtyping


class X:
    x: int
    y: str


class A:
    q: str
    a: str
    b: int
    c: List[X]


if __name__ == '__main__':
    print("\r\n-----json-------")
    json_obj = json.loads('{"q":9, "a":"Mark", "b":3, "c":[{"x":15, "y":"male"},{"x":9, "y":"female", "z":13}]}')
    typed_obj = objtyping.from_primitive(json_obj, A)
    d_l_obj = objtyping.to_primitive(typed_obj)
    print(json.dumps(d_l_obj))

    sys.exit()

output

-----json-------
{"q": "9", "a": "Mark", "b": 3, "c": [{"x": 15, "y": "male"}, {"x": 9, "y": "female", "z": 13}]}
  • note: here is that the property "q", which was originally a number in the original json structure, is a string in the class variable definition, and after converting it to a business object, its type is now a string - the objtyping tool tries to force a conversion between the base types according to the class definition .*

yaml

demo

import sys
from ruamel.yaml import YAML
from typing import List
from objtyping import objtyping


class X:
    x: int
    y: str


class A:
    q: str
    a: str
    b: int
    c: List[X]


if __name__ == '__main__':
    print("\r\n-----yaml-------")
    yaml = YAML()
    yaml_obj = yaml.load('''
    q: 9
    a: Mark
    b: 3
    c:
        - x: 15
          y: male
        - x: 9
          y: female
          z: 13    
    ''')
    typed_obj = objtyping.from_primitive(yaml_obj, A)
    d_l_obj = objtyping.to_primitive(typed_obj)
    yaml.dump(d_l_obj, sys.stdout)

    sys.exit()

output

-----yaml-------
q: '9'
a: Mark
b: 3
c:
- x: 15
  y: male
- x: 9
  y: female
  z: 13

Here the datatype of property "q" is also converted.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

objtyping-0.5.1.tar.gz (11.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

objtyping-0.5.1-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file objtyping-0.5.1.tar.gz.

File metadata

  • Download URL: objtyping-0.5.1.tar.gz
  • Upload date:
  • Size: 11.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for objtyping-0.5.1.tar.gz
Algorithm Hash digest
SHA256 adb64cf87d43a800e309c10cd9372cffe57d5978086b065c7f0d4be2e9785334
MD5 3733c6f9b475b5fffd800647bfac810b
BLAKE2b-256 118d349613d64c2f1f91cb973f2ee8eafdcf35003927380d1426d525cff5ab9c

See more details on using hashes here.

File details

Details for the file objtyping-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: objtyping-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for objtyping-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 50e3ee779eb463b5f46d2de1441b42969b8203ec91aea5ca4906cd79d7a38f52
MD5 437944283967078fb5c222289a2a65a7
BLAKE2b-256 cdfbe7b91602be29fe149ed2f25b54d996d595bb79f2cc04323134ad00c9cd8a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page