Skip to content Skip to sidebar Skip to footer

Can I Define A __repr__ For A Class Rather Than An Instance?

Can I define a __repr__ for a class rather than an instance? For example, I'm trying to do this class A(object): @classmethod def __repr__(cls): return 'My class %s

Solution 1:

You need to define __repr__ on the metaclass.

classMeta(type):
    def __repr__(cls):
        return'My class %s' % cls.__name__

classA(object):
    __metaclass__ = Meta

__repr__ returns a representation of an instance of an object. So by defining __repr__ on A, you're specifying what you want repr(A()) to look like.

To define the representation of the class, you need to define how an instance of type is represented. In this case, replace type with a custom metaclass with __repr__ defined as you need.

>> repr(A)
My classA

If you want to define a custom __repr__ for each class, I'm not sure there's a particularly clean way to do it. But you could do something like this.

classMeta(type):
    def__repr__(cls):
        ifhasattr(cls, '_class_repr'):
            returngetattr(cls, '_class_repr')()
        else:
            returnsuper(Meta, cls).__repr__()

classA(object):
    __metaclass__ = Meta

    @classmethoddef_class_repr(cls):
        return'My class %s' % cls.__name__

classB(object):
    __metaclass__ = Meta

Then you can customize on a per-class basis.

>> repr(A)
My classA>> repr(B)
<__main__.B object at 0xb772068c>

Solution 2:

Can I define a __repr__ for a class rather than an instance?

Sure, I demonstrate here, with a __repr__ that passes the repr test.

classType(type):
    def__repr__(cls):
        """
        >>> Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        """
        name = cls.__name__
        parents = ', '.join(b.__name__ for b in cls.__bases__)
        if parents:
            parents += ','
        namespace = ', '.join(': '.join(
          (repr(k), repr(v) ifnotisinstance(v, type) else v.__name__)) 
               for k, v in cls.__dict__.items())
        return'Type(\'{0}\', ({1}), {{{2}}})'.format(name, parents, namespace)

    def__eq__(cls, other):
        return (cls.__name__, cls.__bases__, cls.__dict__) == (
                other.__name__, other.__bases__, other.__dict__)

And to demonstrate:

classFoo(object): pass

classBar(object): pass

Either Python 2:

classBaz(Foo, Bar): 
    __metaclass__ = Type

Or Python 3:

classBaz(Foo, Bar, metaclass=Type): 
    pass

Or fairly universally:

Baz = Type('Baz', (Foo, Bar), {})
>>> Baz
Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})

And to do the repr test:

defmain():
    print Baz
    assert Baz == eval(repr(Baz))

What is the repr test? It's the above test from the documentation on repr:

>>> help(repr)
Help on built-infunction repr inmodule __builtin__:

repr(...)
    repr(object) -> stringReturn the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

Post a Comment for "Can I Define A __repr__ For A Class Rather Than An Instance?"