Can I Define A __repr__ For A Class Rather Than An Instance?
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?"