2015-10-02 5 views
9

Будучи усталым, вручную применяя строковое представление для моих классов, мне было интересно, есть ли питонический способ сделать это автоматически.Есть ли способ автоматически генерировать реализацию __str __() в python?

Я хотел бы получить вывод, который охватывает все атрибуты класса и имени класса. Вот пример:

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 

Результирующее в:

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

Этот вопрос пришел в голову после того, как с помощью Project Ломбок @ToString в некоторых проектах Java.

+0

Что Проект Ломбок делает для Java? –

+0

Сокращение кода котла. Посмотрите здесь: https://projectlombok.org/features/index.html –

+1

Собственно, «сокращение кода шаблона» ничего не значит. Ломбок занимается конкретными проблемами Java. Бесполезно искать «аналогичный» инструмент, лучше попросить что-то более конкретное. –

ответ

16

Вы можете перебирать instnace атрибутов с помощью 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

написал это в то время как falsetru answerred. Его же идея, мой очень начинающий дружественные с точки зрения прочтения, его гораздо лучше реализована имхо

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)