2009-04-15 6 views

Respuesta

3

¿Quieres decir

__dict__ 

?

8

Sí, se puede hacer una clase "AutoRepr" y dejar que todas las demás clases amplían:

>>> class AutoRepr(object): 
...  def __repr__(self): 
...   items = ("%s = %r" % (k, v) for k, v in self.__dict__.items()) 
...   return "<%s: {%s}>" % (self.__class__.__name__, ', '.join(items)) 
... 
>>> class AnyOtherClass(AutoRepr): 
...  def __init__(self): 
...   self.foo = 'foo' 
...   self.bar = 'bar' 
... 
>>> repr(AnyOtherClass()) 
"<AnyOtherClass: {foo = 'foo', bar = 'bar'}>" 

Tenga en cuenta que el código anterior no actuará muy bien en las estructuras de datos que hacen referencia a sí mismos (ya sea directa o indirectamente) . Como alternativa, se puede definir una función que funciona en cualquier tipo:

>>> def autoRepr(obj): 
...  try: 
...   items = ("%s = %r" % (k, v) for k, v in obj.__dict__.items()) 
...   return "<%s: {%s}." % (obj.__class__.__name__, ', '.join(items)) 
...  except AttributeError: 
...   return repr(obj) 
... 
>>> class AnyOtherClass(object): 
...  def __init__(self): 
...   self.foo = 'foo' 
...   self.bar = 'bar' 
... 
>>> autoRepr(AnyOtherClass()) 
"<AnyOtherClass: {foo = 'foo', bar = 'bar'}>" 
>>> autoRepr(7) 
'7' 
>>> autoRepr(None) 
'None' 

Tenga en cuenta que la función anterior no se define de forma recursiva, a propósito, por la razón mencionada anteriormente.

+0

__dict__ no muestra la clase AnyOtherClass (objeto): foo = 'hello' –

1

Bueno, he jugado un poco con otras respuestas y se puso una solución muy bonita:

class data: 
    @staticmethod 
    def repr(obj): 
     items = [] 
     for prop, value in obj.__dict__.items(): 
      try: 
       item = "%s = %r" % (prop, value) 
       assert len(item) < 20 
      except: 
       item = "%s: <%s>" % (prop, value.__class__.__name__) 
      items.append(item) 

     return "%s(%s)" % (obj.__class__.__name__, ', '.join(items)) 

    def __init__(self, cls): 
     cls.__repr__ = data.repr 
     self.cls = cls 

    def __call__(self, *args, **kwargs): 
     return self.cls(*args, **kwargs) 

Se utiliza como decorador:

@data 
class PythonBean: 
    def __init__(self): 
     self.int = 1 
     self.list = [5, 6, 7] 
     self.str = "hello" 
     self.obj = SomeOtherClass() 

y obtener un inteligente __repr__ fuera de la caja:

PythonBean(int = 1, obj: <SomeOtherClass>, list = [5, 6, 7], str = 'hello') 

Esto funciona con cualquier clase recursiva, incluidas las estructuras de árbol. Si intenta poner una autorreferencia en la clase self.ref = self, la función intentará (con éxito) resolverlo durante aproximadamente un segundo.

Por supuesto, siempre la mente de su jefe - el mío no le gustaría un azúcar tal sintaxis))

5

manera más simple:

def __repr__(self): 
    return str(self.__dict__) 
0

utilizo esta función auxiliar para generar repr s para mis clases . Es fácil de ejecutar en una función de prueba unitaria, es decir.

def test_makeRepr(self): 
    makeRepr(Foo, Foo(), "anOptional space delimitedString ToProvideCustom Fields") 

esta debe ser la salida de un número potencial repr a la consola, que luego se puede copiar/pegar en su clase.

def makeRepr(classObj, instance = None, customFields = None): 
    """Code writing helper function that will generate a __repr__ function that can be copy/pasted into a class definition. 

    Args: 
     classObj (class): 
     instance (class): 
     customFields (string): 

    Returns: 
     None: 

    Always call the __repr__ function afterwards to ensure expected output. 
    ie. print(foo) 

    def __repr__(self): 
     msg = "<Foo(var1 = {}, var2 = {})>" 
     attributes = [self.var1, self.var2] 
     return msg.format(*attributes) 
    """ 
    if isinstance(instance, classObj): 
     className = instance.__class__.__name__ 
    else: 
     className=classObj.__name__ 

    print('Generating a __repr__ function for: ', className,"\n") 
    print("\tClass Type: "+classObj.__name__, "has the following fields:") 
    print("\t"+" ".join(classObj.__dict__.keys()),"\n") 
    if instance: 
     print("\tInstance of: "+instance.__class__.__name__, "has the following fields:") 
     print("\t"+" ".join(instance.__dict__.keys()),"\n") 
    else: 
     print('\tInstance of: Instance not provided.\n') 

    if customFields: 
     print("\t"+"These fields were provided to makeRepr:") 
     print("\t"+customFields,"\n") 
    else: 
     print("\t"+"These fields were provided to makeRepr: None\n") 
    print("Edit the list of fields, and rerun makeRepr with the new list if necessary.\n\n") 

    print("repr with class type:\n") 
    classResult = buildRepr(classObj.__name__, " ".join(classObj.__dict__.keys())) 
    print(classResult,"\n\n") 

    if isinstance(instance, classObj): 
     instanceResult = buildRepr(instance.__class__.__name__, " ".join(instance.__dict__.keys())) 
    else: 
     instanceResult = "\t-----Instance not provided." 
    print("repr with instance of class:\n") 
    print(instanceResult,"\n\n") 

    if customFields: 
     customResult = buildRepr(classObj.__name__, customFields) 
    else: 
     customResult = '\t-----Custom fields not provided' 
    print("repr with custom fields and class name:\n") 
    print(customResult,"\n\n")  

    print('Current __repr__') 
    print("Class Object: ",classObj) 
    if instance: 
     print("Instance: ",instance.__repr__()) 
    else: 
     print("Instance: ", "None") 


def buildRepr(typeName,fields): 
    funcDefLine = "def __repr__(self):" 
    msgLineBase = ' msg = "<{typename}({attribute})>"' 
    attributeListLineBase = ' attributes = [{attributeList}]' 
    returnLine = ' return msg.format(*attributes)' 
    x = ['self.' + x for x in fields.split()] 
    xResult = ", ".join(x) 
    y = [x + ' = {}' for x in fields.split()] 
    yResult = ', '.join(y) 
    msgLine = msgLineBase.format(typename = typeName, attribute = yResult) 
    attributeListLine = attributeListLineBase.format(attributeList = xResult) 
    result = "{declaration}\n{message}\n{attributes}\n{returnLine}".format(declaration = funcDefLine, 
                     message = msgLine, 
                     attributes = attributeListLine, 
                     returnLine =returnLine) 
    return result