Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 17389

What is JSONEncoder c_make_encoder?

$
0
0

I LOVE the python module json, and I love json.dumps(); however, I hate the fact that you need to pass additional arguments to it if you want to extend its behaviour.

I am strong believer that classes should take care of themselves, so I created the class Serialisable that goes like this:

class Serialisable(dict[str, Any]):    def __len__(self) -> int:        return len(self.items())    def __str__(self) -> str:        return str(dict(self.items()))    def __getitem__(self, __key: str) -> Any:         return getattr(self, __key)    def __setitem__(self, __key: str, __value: Any) -> None:        vars(self)[__key] = __value    def __delitem__(self, __key: str) -> None:        variable = getattr(self, __key)        del variable    def __contains__(self, __key: str) -> bool:        return __key in vars(self)    def __iter__(self) -> Iterator[str]:        return self.keys().__iter__()    def keys(self) -> list[str]:        return [keys for keys, _ in self.items()]    def values(self) -> list[Any]:        return [values for _, values in self.items()]    def items(self) -> list[tuple[str, Any]]:        result: list[tuple[str, Any]] = []        for name, value in vars(self).items():            variable = getattr(self, name)            if isinstance(variable, Serialisable): pass            elif 'builtin' not in variable.__class__.__module__: continue            result.append((name, value))        return result

Basically, if you have a sub class of Serialisable, all of the instance variables (that are serialisable) will appear as part of a dictionary:

@dataclassclass subSerial(Serialisable):    boolean: bool = True    real: float = -1.0@dataclassclass NonSerial:    string: str = 'Miguel'class mainSerial(Serialisable):    def __init__(self) -> None:        self.string: str = 'Calgary'        self.integer: int = 53        self.subClass: subSerial = subSerial()        self.name: dict[str, str] = {'King': 'Charles'}        self.discard: NonSerial = NonSerial()print(f"{serial}")

{'string': 'Calgary', 'integer': 53, 'subClass': subSerial(boolean=True, real=-1.0), 'name': {'King': 'Charles'}}

If I run this code print(f"JSON indent = {json.dumps(serial, sort_keys=True, indent=4)}")

I get this pretty result:

JSON indent = {"integer": 28,"name": {"King": "Charles"    },"string": "Calgary","subClass": {"boolean": true,"real": -1.0    }}

If I remove the indent=4, I get this:

JSON NON indent = {}

Long story short, it all boils down to how Python has implemented json.dumps() and this piece of code on encoder.py

        if (_one_shot and c_make_encoder is not None                and self.indent is None):            _iterencode = c_make_encoder(                markers, self.default, _encoder, self.indent,                self.key_separator, self.item_separator, self.sort_keys,                self.skipkeys, self.allow_nan)        else:            _iterencode = _make_iterencode(                markers, self.default, _encoder, self.indent, floatstr,                self.key_separator, self.item_separator, self.sort_keys,                self.skipkeys, _one_shot)        return _iterencode(o, 0)

c_make_encoderseems to be an external library function (written in C?) that apparently doesn't understand how custom dictionaries work!

So, here is(are) my question(s):

  1. Do you know what I am missing on my Serialisable class to make it act a like a full dictionary and json.dumps()serialises it properly? alternatively
  2. Do you know where can I find the code of c_make_encoder?

(I have found this very useless code on _json.pyi)

@finalclass make_encoder:    @property    def sort_keys(self) -> bool: ...    @property    def skipkeys(self) -> bool: ...    @property    def key_separator(self) -> str: ...[...]

Viewing all articles
Browse latest Browse all 17389

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>