pythonooprepresentation

How do I create a representation when my constructor has added kwargs?


How do I create a representation when my constructor has added kwargs?

class Thing:
    def __init__(self, a, b, **kwargs):
        self.a = a
        self.b = b
        self.__dict__.update(kwargs)

#     def __repr__(self):
#         return ???

thing1 = Thing(6, 5, color="red")

Solution

  • Assuming your exact scenario (i.e. every parameter is assigned to an attribute as-is), this should work:

    class Thing:
        def __init__(self, a, b, **kwargs):
            self.a = a
            self.b = b
            self.__dict__.update(kwargs)
    
        def __repr__(self):
            argnames = self.__init__.__code__.co_varnames[1:self.__init__.__code__.co_argcount] 
            attrdict = dict(self.__dict__)
            args = [repr(attrdict.pop(k)) for k in argnames]
            kwargs = [f"{k}={repr(v)}" for k, v in attrdict.items()]
            return f"{self.__class__.__name__}({', '.join(args + kwargs)})"
    
    thing1 = Thing(6, 5, color="red")
    print(repr(thing1))
    

    Note that it does not detect cycles, and it depends on correct representation of each attribute's value.

    Of course, you can also simplify the code by hardcoding the argument names, since you know them:

    def __repr__(self):
        argnames = ["a", "b"]
        # ...