让我感到__repr__()
困扰的是,一个类的默认值是如此无信息:
>>> class Opaque(object): pass
...
>>> Opaque()
<__main__.Opaque object at 0x7f3ac50eba90>
...所以我一直在考虑如何改进它。经过一番考虑,我想出了这个利用pickle
协议__getnewargs__()
方法的抽象基类:
from abc import abstractmethod
class Repro(object):
"""Abstract base class for objects with informative ``repr()`` behaviour."""
@abstractmethod
def __getnewargs__(self):
raise NotImplementedError
def __repr__(self):
signature = ", ".join(repr(arg) for arg in self.__getnewargs__())
return "%s(%s)" % (self.__class__.__name__, signature)
这是其用法的一个简单示例:
class Transparent(Repro):
"""An example of a ``Repro`` subclass."""
def __init__(self, *args):
self.args = args
def __getnewargs__(self):
return self.args
...以及由此产生的repr()
行为:
>>> Transparent("an absurd signature", [1, 2, 3], str)
Transparent('an absurd signature', [1, 2, 3], <type 'str'>)
>>>
现在,我可以看到 Python 在默认情况下不立即执行此操作的一个原因 - 要求每个类定义一个__getnewargs__()
方法比期望(但不要求)它定义一个__repr__()
方法更加繁琐。
我想知道的是:它有多危险和/或脆弱?副手,我想不出任何可能出错的地方,除非一个Repro
实例包含自己,你会得到无限递归......但这是可以解决的,代价是使上面的代码更丑陋。
我还错过了什么?