加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 如何正确实现__str__和__repr__

发布时间:2020-12-20 12:01:52 所属栏目:Python 来源:网络整理
导读:在我的几个类中,我想实现__str__和__repr__,并且通常最终得到如下代码: class MyClass(object): def __init__(self,a): self.a = a def __str__(self): return 'MyClass({})'.format(self.a) def __repr__(self): return 'MyClass({!r})'.format(self.a) 这
在我的几个类中,我想实现__str__和__repr__,并且通常最终得到如下代码:

class MyClass(object):
    def __init__(self,a):
        self.a = a

    def __str__(self):
        return 'MyClass({})'.format(self.a)

    def __repr__(self):
        return 'MyClass({!r})'.format(self.a)

这符合我的期望:

>>> myobject = MyClass(np.array([1,2]))
>>> str(myobject)
'MyClass([1 2])'
>>> repr(myobject)
'MyClass(array([1,2]))'

然而,代码违反DRY并且随着参数的数量开始增长而保持这变得很麻烦,我经常发现__str__或__repr__中的任何一个与另一个“不同步”.

有没有更好的方法同时实现__str__和__repr__而不重复?

解决方法

由于__str __和__repr__遵循相同的模式,因此您可以编写一个函数来为您创建对象的字符串表示形式.它需要一个对象,一个属性列表和str或repr作为参数:

def stringify(obj,attrs,strfunc):
    values = []
    # get each attribute's value and convert it to a string
    for attr in attrs:
        value = getattr(obj,attr)
        values.append(strfunc(value))

    # get the class name
    clsname = type(obj).__name__

    # put everything together
    args = ','.join(values)
    return '{}({})'.format(clsname,args)

print( stringify(MyClass('foo'),['a'],repr) )
# output: MyClass('foo')

我建议将此函数放在一个继承自的类中:

class Printable:
    def __str__(self):
        return self.__stringify(str)

    def __repr__(self):
        return self.__stringify(repr)

    def __stringify(self,strfunc):
        values = []
        for attr in self._attributes:
            value = getattr(self,attr)
            values.append(strfunc(value))

        clsname = type(self).__name__
        args = ','.join(values)
        return '{}({})'.format(clsname,args)

class MyClass(Printable):
    _attributes = ['a']

    def __init__(self,a):
        self.a = a

您甚至可以通过直接从__init__函数的签名中获取属性来完全自动完成它:

import inspect

class AutoPrintable:
    def __str__(self):
        return self.__stringify(str)

    def __repr__(self):
        return self.__stringify(repr)

    def __stringify(self,strfunc):
        sig= inspect.signature(self.__init__)
        values= []
        for attr in sig.parameters:
            value= getattr(self,attr)
            values.append(strfunc(value))

        clsname= type(self).__name__
        args= ',args)

class MyClass(AutoPrintable):
    def __init__(self,a,b):
        self.a = a
        self.b = b

print( str(MyClass('foo','bar')) ) # output: MyClass(foo,bar)
print( repr(MyClass('foo','bar')) ) # output: MyClass('foo','bar')

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读