<p>我可以想出四种方法来产生“相同”<code>__str__</code>和{<cd2>}方法。。。不算复制和粘贴之类的错误。在</p>
<p>(对于这些示例,我使用的是一个精简的<code>ClusterAssignment</code>类,它没有任何意义的字符串表示形式,没有其他方法。)</p>
<p>您可以使用Tim Castelijns的方法和一个单独的“private”<code>_str</code>方法,该方法由<code>__str__</code>和{<cd2>}调用:</p>
<pre><code>class ClusterAssignment(object):
def _str(self):
return "[string]"
def __str__(self):
return self._str()
def __repr__(self):
return self._str()
</code></pre>
<p>这是可行的,但需要在这两个函数的主体中重复自己。在</p>
<p>为了避免重复,可以正常编写<code>__str__</code>或{<cd2>}中的一个,然后让另一个方法只调用“real”方法。您编写的“真正的”方法取决于您的预期输出-它是更“stringy”还是“repr-y”?在</p>
<p>“调用‘real’方法有两种方法:使用dunder方法(下面的第一个示例)或使用公共接口(第二个示例)。我建议使用公共界面,因为这是你的用户必须做的。在</p>
^{pr2}$
<p>最后,您可以给一个“real”方法一个别名:</p>
<pre><code>class ClusterAssignment(object):
def __str__(self):
return "[string]"
__repr__ = __str__
</code></pre>
<p>这里没有重复,也没有多余的方法定义:<code>__repr__</code><em>是</em><code>__str__</code>。在</p>
<p>我认为这是显式的(比隐式的好)——只执行一个任务,所以只有一个方法。其他人可能会认为这是相反的-现在有两个名字伪装成两个方法,而实际上只有一个。而且,它们在源代码中的顺序现在很重要-<code>__repr__</code><em>必须在<code>__str__</code>之后定义。在</p>
<p>别名技术的一个怪癖是:<em>方法本身的字符串表示现在也完全相同了。前三个版本产生:</p>
<pre><code>>>> ca = ClusterAssignment()
>>> print(ca.__str__)
<bound method ClusterAssignment.__str__ of [string]>
>>> print(ca.__repr__)
<bound method ClusterAssignment.__repr__ of [string]>
</code></pre>
<p>别名版本清楚地表明只有一种方法:</p>
<pre><code>>>> ca = ClusterAssignment()
>>> print(ca.__str__)
<bound method ClusterAssignment.__str__ of [string]>
>>> print(ca.__repr__)
<bound method ClusterAssignment.__str__ of [string]>
</code></pre>
<p>…或者它会让你的同事去寻找在应该调用<code>__repr__</code>时调用<code>__str__</code>的窃听上线。在</p>
<p>什么样的项目指南是这种风格的决定。在</p>