2012-01-21 14 views
11

¿Puedo definir una __repr__ para una clase en lugar de una instancia? Por ejemplo, yo estoy tratando de hacer esto¿Puedo definir un __repr__ para una clase en lugar de una instancia?

class A(object): 
    @classmethod 
    def __repr__(cls): 
     return 'My class %s' % cls 

Lo que se ve es

In [58]: a=A() 

In [59]: a 
Out[59]: My class <class '__main__.A'> 

In [60]: A 
Out[60]: __main__.A 

Estoy intentando conseguir la salida de la línea 60 para parecerse a "Mi Clase A", no para la instancia a. La razón por la que quiero hacer esto es generar muchas clases utilizando la metaclase de Python. Y quiero una forma más legible para identificar la clase que la repr de stock.

+0

Entiende mal tu problema. Publicado otra respuesta (con suerte correcta). –

Respuesta

18

es necesario definir __repr__ en la metaclase.

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

class A(object): 
    __metaclass__ = Meta 

__repr__ devuelve una representación de una instancia de un objeto. Así definiendo __repr__ en A, que está especificando lo que quiere repr(A()) para que parezca.

Para definir la representación de la clase, es necesario definir cómo se representa una instancia de type. En este caso, reemplace type con una metaclase personalizada con __repr__ definida como la necesita.

>> repr(A) 
My class A 

Si desea definir una costumbre __repr__ para cada clase, no estoy seguro de que hay una manera particularmente limpia para hacerlo. Pero podrías hacer algo como esto.

class Meta(type): 
    def __repr__(cls): 
     if hasattr(cls, '_class_repr'): 
      return getattr(cls, '_class_repr')() 
     else: 
      return super(Meta, cls).__repr__() 

class A(object): 
    __metaclass__ = Meta 

    @classmethod 
    def _class_repr(cls): 
     return 'My class %s' % cls.__name__ 

class B(object): 
    __metaclass__ = Meta 

A continuación, puede personalizar según las clases.

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

Pásame, +1. –

+3

Tenga en cuenta que en Python 3 '__metaclass__' no tiene ningún significado especial, sino que debe usar' clase A (metaclass = Meta) '. –

+0

@RobWouters Gracias :) No me di cuenta de que había cambiado. –

0

¿Puedo definir una __repr__ para una clase en lugar de una instancia?

Claro, lo demuestran aquí, con un __repr__ que pasa la prueba repr.

class Type(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) if not isinstance(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__) 

Y para demostrar:

class Foo(object): pass 

class Bar(object): pass 

De cualquier Python 2:

class Baz(Foo, Bar): 
    __metaclass__ = Type 

o Python 3:

class Baz(Foo, Bar, metaclass=Type): 
    pass 

o bastante universal:

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

Y para hacer la prueba de repr:

def main(): 
    print Baz 
    assert Baz == eval(repr(Baz)) 

¿Cuál es la prueba repr?Es la prueba anterior de la documentación en repr:

>>> help(repr) 
Help on built-in function repr in module __builtin__: 

repr(...) 
    repr(object) -> string 

    Return the canonical string representation of the object. 
    For most object types, eval(repr(object)) == object. 
Cuestiones relacionadas