【问题标题】:Is there a way to auto generate a __str__() implementation in python?有没有办法在 python 中自动生成 __str__() 实现?
【发布时间】:2015-10-02 14:58:59
【问题描述】:

厌倦了为我的类手动实现字符串表示,我想知道是否有一种 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)

在一些 Java 项目中使用 Project Lombok @ToString 后想到这个问题。

【问题讨论】:

  • Project Lombok 为 Java 做了什么?
  • 样板代码缩减。在此处查找功能:projectlombok.org/features/index.html
  • 其实,“样板代码缩减”没有任何意义。 Lombok 处理特定的 Java 问题。搜索“类似”的工具是没有用的,最好问更具体的。
  • Python 默认实现__str__,转发到__repr____repr__ 也有一个默认实现,它提到了type(my_object)id(my_object) 的结果。如果您想使用其他默认值,您可以 a) 使用继承,b) 编写自己的类装饰器,或 c) 将类主体中的 __str__ 分配给某个现有函数(通过执行 __str__ = something 而不是 def __str__(self) )。

标签: python boilerplate


【解决方案1】:

您可以使用varsdir、...来迭代实例属性:

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)'

【讨论】:

    【解决方案2】:

    在 falsetru 回答时写了这个。 它的想法是一样的,我的在阅读方面对初学者非常友好,他的实现要好得多恕我直言

    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)
    

    【讨论】:

      猜你喜欢
      • 2020-08-09
      • 1970-01-01
      • 2012-03-27
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 2018-10-30
      • 2020-11-13
      相关资源
      最近更新 更多