它的錯誤我是一類的默認__repr__()
是如此無信息:這個抽象基類帶有「更好的」__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不會立即執行 - requiri每個班級定義一個__getnewargs__()
方法將比預期(但不要求)它定義一個__repr__()
方法更負擔。
我想知道的是:它有多危險和/或脆弱?副手,我想不出任何可能會出現嚴重錯誤的情況,除非如果一個Repro
實例包含它自己,你會得到無限遞歸...但是這是可以解決的,代價是使代碼高於醜陋。
我還錯過了什麼?
'repr'大約是* *的方式之前存在着任何東西,如'__getnewargs__'。你也在濫用一種方法。它是由一個庫模塊(而不是python語言核心本身)引入的,可以完成一個完全不同的事情。還有關鍵字參數呢?在python3中,可以只有構造函數的關鍵字參數。 此外,我沒有看到任何真正的額外好處。對象可以有一個簡單的字符串表示*應該*來實現'__repr__'和/或'__str__'。使用你的方法,你仍然需要重新實現它,或者你必須重新實現'__getnewargs__'。 – Bakuriu
沒有真正的理由爲此使用'__getnewargs__',是嗎?你可以定義一個約定,一個對象將一些識別信息存儲在一個任意屬性中(比如'_reprInfo'),然後'__repr__'輸出'self._reprInfo'。 – BrenBarn
@Bakuriu我怎麼濫用它呢?一個正確實現的'Repro'的子類將有一個正確的每個pickle'__getnewargs __()',這甚至可以被認爲是一個優點。我意識到這不適用於具有關鍵字參數構造函數的類,但是我不會將它用於這些......實際上,如果可以,我會盡量避免構造函數中的關鍵字參數。 –