考虑以下课程:
class ClusterAssignment(object):
def __init__(self, id, cluster):
self.id = long(id)
self.cluster = long(cluster)
@property
def id(self):
return self._java_model.id()
@property
def cluster(self):
return self._java_model.cluster()
def __str__(self):
return self._str()
def _str(self):
return "(%d,%d)" %(self.id(), self.cluster())
def __repr__(self):
return self._str()
覆盖 str 和 repr 的尝试不正确:它们未被使用。
ClusterAssignment(22, 234234)
Out[100]: <__main__.ClusterAssignment at 0x104ab3090>
现在有一个现有的SOF名义上解决了这个问题:
Overriding special methods on an instance
然而,目前尚不清楚如何应用上述案例中提供的解决方案。
具体来说:当调用 str 或 repr 时,如何配置自定义_str()?
更新我在使用 str 与_str()方法进行了拼写错误,将其简化为在SOF上显示。更正后的代码也会出现相同的结果 - 上面已更新。
答案 0 :(得分:3)
我认为您在自己的代码中实现了解决方法时遇到了一些错误,而您实际想要的更像是
def __str__(self):
return self._str()
def __repr__(self):
return self._str()
def _str(self):
return "(%d,%d)" %(self.id(), self.cluster())
因此,只要调用__str__()
或__repr__()
,就会返回_str()
答案 1 :(得分:1)
我可以想出四种方法来制作“相同的”__str__
和__repr__
方法...不要像复制和放大一样计算可怕性糊。
(对于这些示例,我使用了一个带有无意义字符串表示的精简ClusterAssignment
类,而没有其他方法。)
您可以使用Tim Castelijns的方法,使用_str
和__str__
调用的单个“私有”__repr__
方法:
class ClusterAssignment(object):
def _str(self):
return "[string]"
def __str__(self):
return self._str()
def __repr__(self):
return self._str()
这有效,但需要在两个函数的主体中重复自己。
为避免重复,您可以正常编写__str__
或__repr__
中的一个,然后让另一个方法除了调用“真实”方法之外什么也不做。你写的“真实”的方法取决于你的预期输出 - 它是“更多”或更“重复”吗?
有两种方法可以“调用'真实'方法”:使用dunder方法(下面的第一个示例),或使用公共接口(第二个示例)。我建议使用公共界面,因为这是用户必须做的事情。
class ClusterAssignment(object):
def __str__(self):
return "[string]"
def __repr__(self):
# Uses "private" dunder-method.
return self.__str__()
class ClusterAssignment(object):
def __str__(self):
return "[string]"
def __repr__(self):
# Uses public interface.
return str(self)
最后,您可以为一个“真实”方法添加别名:
class ClusterAssignment(object):
def __str__(self):
return "[string]"
__repr__ = __str__
此处不重复,且没有多余的方法定义:__repr__
__str__
。
我认为这是明确的(比隐含更好)---只执行了一个任务,所以只有一个方法。其他人可能会认为这是相反的 - 现在有两个伪装成两个方法的名称,当时只有一个。此外,他们在源代码中的顺序现在很重要--- __repr__
必须在__str__
之后定义。
混叠技术的一个奇怪之处:<em>方法本身的字符串表示现在也是相同的。前三个版本产生:
>>> ca = ClusterAssignment()
>>> print(ca.__str__)
<bound method ClusterAssignment.__str__ of [string]>
>>> print(ca.__repr__)
<bound method ClusterAssignment.__repr__ of [string]>
别名版本清楚地表明只有一种方法:
>>> ca = ClusterAssignment()
>>> print(ca.__str__)
<bound method ClusterAssignment.__str__ of [string]>
>>> print(ca.__repr__)
<bound method ClusterAssignment.__str__ of [string]>
...或者它会让你的同事在应该拨打__str__
时拨打__repr__
的警告线。
这种决定是项目风格指南的用途。