【问题标题】:Python: How to write __repr__ when having __slots__Python:当有 __slots__ 时如何编写 __repr__
【发布时间】:2020-12-26 02:44:09
【问题描述】:

我想知道如何为具有__slots__ 的类实现__repr__ 方法。据我了解__repr__,它应该返回一个字符串,该字符串可用于构造我们称为__repr__ 的对象。换句话说,将repr(object) 提供给Python 解释器应该构造object

但是,如果有一个类有__slots__,我很难想象如何实现它。这是因为在使用__slots__ 时,插槽中的某些属性可能已初始化并具有值,而其他属性可能不会。那么如何确定哪些属性已初始化以及将它们传递给__repr__ 字符串的值呢?

此类的最小示例:

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)

有什么建议吗?

【问题讨论】:

    标签: python class slots repr


    【解决方案1】:

    据我了解__repr__,它应该返回一个字符串,该字符串可用于构造我们称为__repr__ 的对象。换句话说,将repr(object) 提供给 Python 解释器应该构造对象。

    这只是一个建议,而不是强制:

    如果可能的话,这应该看起来像一个有效的 Python 表达式,可用于重新创建具有相同值的对象(给定适当的环境)。如果这不可行,则应返回 <...> 形式的字符串。

    并且“如果可能”的解释非常松散和弱,许多对象根本不会打扰,例如类或函数的 repr 可以产生其源表示,但不要这样做,因为它几乎没有用例,而且它更烦人而不是有用。

    但是,如果有一个类有__slots__,我很难想象如何实现它。这是因为在使用__slots__ 时,槽中的某些属性可能已初始化并具有值,而其他可能不会。

    当然不是。我从来没有写过一个有插槽的类,并不是所有的插槽都一直被填满。加上hasattr/getattr 与插槽配合得很好。

    虽然我不得不问:你是货物崇拜__slots__吗?是否有人曾经告诉您使用插槽,而现在您到处都在使用它们?

    slots 是一种 内存优化 工具,例如,要点是每个成员只需要一个指针(+ 一些对象开销),而不是 dict 实例的开销(及其摊销的重新分配)。当您通常不填充插槽时使用插槽几乎没有意义,更不用说将__dict__ 添加到插槽。

    更不用说最近的 Python 3 迭代已经为 instance-dicts 添加了各种优化,这使得 slot 变得不那么有用了,至少随着属性数量的增加(在 3.6 的相当大的类上,我们发现差异不到 5%,尽管在小班,它可能仍然很重要)。

    【讨论】:

    • 我通常不使用插槽。尽管如此,内存优化总是一件好事还是我弄错了?回到问题:所以你的建议是只产生一些有用的字符串而不是对象的完整呈现?在“Fluent Python”中,作者写道__repr__“应该(...)匹配重新创建被表示对象所需的源代码”。我打算遵循的正是这个建议。
    • “所以你的建议是只生成一些有用的字符串而不是对象的完整呈现?”是的。我引用的是__repr__的官方文档。
    • 对于我的示例类,我给出的__repr__ 就可以了?我会尽量听从你的建议,把“fluent python”的建议作为理论上的最佳选择;)
    • 当然,如果它符合您的需求。
    猜你喜欢
    • 2014-10-21
    • 2012-08-31
    • 1970-01-01
    • 2021-05-07
    • 2020-02-22
    • 2015-07-29
    • 2011-12-07
    • 2011-06-30
    • 2021-04-08
    相关资源
    最近更新 更多