在自定义python类上转换自定义__repr __,__ rs__的细节

时间:2015-04-06 23:16:29

标签: python

考虑以下课程:

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上显示。更正后的代码也会出现相同的结果 - 上面已更新。

2 个答案:

答案 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__的警告线。

这种决定是项目风格指南的用途。