2015-10-02 1 views
9

Etre fatigué manuellement en implémentant une représentation de chaîne pour mes cours, je me demandais s'il y avait une façon pythonique de le faire automatiquement.Existe-t-il un moyen de générer automatiquement une implémentation de __str __() en python?

Je voudrais avoir une sortie qui couvre tous les attributs de la classe et le nom de la classe. Voici un exemple:

class Foo(object): 
    attribute_1 = None 
    attribute_2 = None 
    def __init__(self, value_1, value_2): 
     self.attribute_1 = value_1 
     self.attribute_2 = value_2 

Entraînant:

bar = Foo("baz", "ping") 
print(str(bar)) # desired: Foo(attribute_1=baz, attribute_2=ping) 

Cette question vient à l'esprit après l'utilisation du projet Lombok @ToString dans certains projets Java.

+0

Quel projet Lombok fait pour Java? –

+0

Réduction du code de la plaque de chaudière. Regardez ici pour les fonctionnalités: https://projectlombok.org/features/index.html –

+1

En fait, "réduction de code passe-partout" ne veut rien dire. Lombok traite de problèmes Java spécifiques. Il est inutile de chercher un outil "similaire", il vaut mieux demander quelque chose de plus concret. –

Répondre

16

Vous pouvez itérer instnace attributs à l'aide vars, dir, ...:

>>> def auto_str(cls): 
...  def __str__(self): 
...   return '%s(%s)' % (
...    type(self).__name__, 
...    ', '.join('%s=%s' % item for item in vars(self).items()) 
...  ) 
...  cls.__str__ = __str__ 
...  return cls 
... 
>>> @auto_str 
... class Foo(object): 
...  def __init__(self, value_1, value_2): 
...   self.attribute_1 = value_1 
...   self.attribute_2 = value_2 
... 
>>> str(Foo('bar', 'ping')) 
'Foo(attribute_2=ping, attribute_1=bar)' 
1

écrit cela en falsetru answerred. Son la même idée, le mien est très amical débutant en termes de lecture, son est beaucoup plus agréable mis en œuvre IMHO

class stringMe(object): 
     def __str__(self): 
      attributes = dir(self) 
      res = self.__class__.__name__ + "(" 
      first = True 
      for attr in attributes: 
       if attr.startswith("__") and attr.endswith("__"): 
        continue 

       if(first): 
        first = False 
       else: 
        res += ", " 

       res += attr + " = " + str(getattr(self, attr)) 

      res += ")" 
      return res 

    class Foo(stringMe): 
     attribute_1 = None 
     attribute_2 = None 
     def __init__(self, value_1, value_2): 
      self.attribute_1 = value_1 
      self.attribute_2 = value_2 


bar = Foo("baz", "ping") 
print(str(bar)) # desired: Foo(attribute_1=baz, attribute_2=ping)