在我的几个类中,我想实现__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')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。