Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Possibility to implement multiple repr strategies?

In Python, is there a way to implement multiple representation strategies on custom classes, to provide different styles how they are shown, and the whole thing recursively on arbitrary data structures, so that nested objects would be represented using the parent call’s strategy, if available? Like this…

class SomeClass:
    def __init__(self, objects):
        self._objects = objects
    def __repr__(self):
        return f"Recursive default repr: {self._objects}"
    def __alternate_repr__(self):
        return f"Recursive alternate repr: {self._objects}"

a = SomeClass(dict(x=1))
b = SomeClass(["list", "of", "values"])
c = SomeClass([a, b, 4, "..."])

repr(c)  # c,a,b shown using __repr__()
alternate_repr(c)  # c,a,b shown using __alternate_repr__()

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You’d probably want repr() to do the right thing (e.g. when called by other library code), and that code wouldn’t know about a __special_repr__ or whatever, so you’ll need some more roundabout plumbing here.

Using contextvars makes sure this is async/threading safe.

import contextlib
import contextvars

## Repr mode plumbing.

_repr_mode = contextvars.ContextVar("repr_mode", default="normal")


def get_repr_mode():
    return _repr_mode.get()


@contextlib.contextmanager
def with_repr_mode(mode):
    try:
        token = _repr_mode.set(mode)
        yield
    finally:
        _repr_mode.reset(token)


## Client classes using the repr mode.


class SomeClass(str):
    def __repr__(self):
        if get_repr_mode() == "special":
            return f"SPECIAL ALL CAPS REPR! {self.upper()}"
        return super().__repr__()


class SomeContainer(list):
    def __repr__(self):
        if get_repr_mode() == "special":
            return f"SPECIAL REPR!: {super().__repr__()}"
        return super().__repr__()


## Demo code.

lst = SomeContainer([SomeClass("hello"), SomeClass("world")])

print(repr(lst))

with with_repr_mode("special"):
    print(repr(lst))

This prints out

['hello', 'world']
SPECIAL REPR!: [SPECIAL ALL CAPS REPR! HELLO, SPECIAL ALL CAPS REPR! WORLD]
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading