Python:有__slots__时如何写__repr__
Python: How to write __repr__ when having __slots__
我想知道如何为 class 和 __slots__
实现 __repr__
方法。据我理解__repr__
,应该是return一个字符串,可以用来构造我们称之为__repr__
的对象。换句话说,给 repr(object)
一个 Python 解释器应该构造 object
.
但是,如果有一个 class 有 __slots__
,我很难想象如何实现它。这是因为当使用 __slots__
时,插槽中的某些属性可能会被初始化并具有值,而其他属性可能不会。那么我如何找出哪些属性被初始化以及将它们传递给 __repr__
字符串的值?
这种 class 的最小示例:
class TestClass:
__slots__ = 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', '__dict__'
def __init__(self, something, something_else, **kwargs):
self.something = something
self.something_else = something_else
for key, value in kwargs.items():
setattr(self, key, value)
def __repr__(self):
return '%s(%r, %r)' %(self.__class__.__name__, self.something, self.something_else)
有什么建议吗?
As far as I understand __repr__
, it is supposed to return a string which can be used to construct the object of which we called __repr__
. In other words, giving repr(object)
to a Python interpreter should construct object.
这只是建议,不是强加:
If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned.
并且“如果可能的话”的解释非常松散和薄弱,许多对象根本不会打扰,例如class 或函数 的 repr 可以 产生其源表示,但不要这样做,因为它的用例很少,而且它比有用更烦人。
However, if there is a class having __slots__
, I find it hard to imagine how to implement this. This is because when using __slots__
, some of the attributes in slots may be initialised and have values, others probably won't.
当然不是。我从来没有写过一个 class 的插槽,其中并非所有插槽都一直被填充。再加上 hasattr
/getattr
可以很好地处理插槽。
尽管我不得不问:你是cargo-culting __slots__
吗?是否有人曾经告诉您使用插槽,现在您到处都在使用它们?
slots 是一个内存优化工具,重点是例如每个成员只需要一个指针(+一些对象开销)而不是 dict 实例的开销(和它的摊销重新分配)。当您通常不填充插槽时使用插槽几乎没有意义,更不用说将 __dict__
添加到您的插槽。
更不用说最近的 Python 3 次迭代已经对 instance-dicts 添加了各种优化,使得插槽的用处更少,至少随着属性数量的增加(在相当大的 classes从 3.6 开始,我们发现差异小于 5%,尽管在小 classes 上它可能仍然很重要)。
我想知道如何为 class 和 __slots__
实现 __repr__
方法。据我理解__repr__
,应该是return一个字符串,可以用来构造我们称之为__repr__
的对象。换句话说,给 repr(object)
一个 Python 解释器应该构造 object
.
但是,如果有一个 class 有 __slots__
,我很难想象如何实现它。这是因为当使用 __slots__
时,插槽中的某些属性可能会被初始化并具有值,而其他属性可能不会。那么我如何找出哪些属性被初始化以及将它们传递给 __repr__
字符串的值?
这种 class 的最小示例:
class TestClass:
__slots__ = 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', '__dict__'
def __init__(self, something, something_else, **kwargs):
self.something = something
self.something_else = something_else
for key, value in kwargs.items():
setattr(self, key, value)
def __repr__(self):
return '%s(%r, %r)' %(self.__class__.__name__, self.something, self.something_else)
有什么建议吗?
As far as I understand
__repr__
, it is supposed to return a string which can be used to construct the object of which we called__repr__
. In other words, givingrepr(object)
to a Python interpreter should construct object.
这只是建议,不是强加:
If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned.
并且“如果可能的话”的解释非常松散和薄弱,许多对象根本不会打扰,例如class 或函数 的 repr 可以 产生其源表示,但不要这样做,因为它的用例很少,而且它比有用更烦人。
However, if there is a class having
__slots__
, I find it hard to imagine how to implement this. This is because when using__slots__
, some of the attributes in slots may be initialised and have values, others probably won't.
当然不是。我从来没有写过一个 class 的插槽,其中并非所有插槽都一直被填充。再加上 hasattr
/getattr
可以很好地处理插槽。
尽管我不得不问:你是cargo-culting __slots__
吗?是否有人曾经告诉您使用插槽,现在您到处都在使用它们?
slots 是一个内存优化工具,重点是例如每个成员只需要一个指针(+一些对象开销)而不是 dict 实例的开销(和它的摊销重新分配)。当您通常不填充插槽时使用插槽几乎没有意义,更不用说将 __dict__
添加到您的插槽。
更不用说最近的 Python 3 次迭代已经对 instance-dicts 添加了各种优化,使得插槽的用处更少,至少随着属性数量的增加(在相当大的 classes从 3.6 开始,我们发现差异小于 5%,尽管在小 classes 上它可能仍然很重要)。