简体   繁体   English

Python:如何在有 __slots__ 时编写 __repr__

[英]Python: How to write __repr__ when having __slots__

I am wondering how to implement the __repr__ method for a class with __slots__ .我想知道如何为带有__slots__的类实现__repr__方法。 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__ .据我了解__repr__ ,它应该返回一个字符串,该字符串可用于构造我们称之为__repr__的对象。 In other words, giving repr(object) to a Python interpreter should construct object .换句话说,将repr(object)提供给 Python 解释器应该构造object

However, if there is a class having __slots__ , I find it hard to imagine how to implement this.但是,如果有一个具有__slots__的类,我很难想象如何实现它。 This is because when using __slots__ , some of the attributes in slots may be initialised and have values, others probably won't.这是因为在使用__slots__ ,插槽中的某些属性可能会被初始化并具有值,而其他的可能不会。 So how do I figure out which attributes were initialised and there values to pass them to the __repr__ string?那么我如何确定哪些属性被初始化以及将它们传递给__repr__字符串的值?

Minimal example of such a 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)

Any suggestions?有什么建议?

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__ .据我了解__repr__ ,它应该返回一个字符串,该字符串可用于构造我们称之为__repr__的对象。 In other words, giving repr(object) to a Python interpreter should construct object.换句话说,将repr(object)赋予 Python 解释器应该构造对象。

That's just a suggestion, not an imposition:这只是一个建议,而不是强加的:

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).如果可能的话,这应该看起来像一个有效的 Python 表达式,可用于重新创建具有相同值的对象(给定适当的环境)。 If this is not possible, a string of the form <...some useful description...> should be returned.如果这是不可能的,则应返回 <...一些有用的描述...> 形式的字符串。

And "if at all possible" is interpreted very loosely and weakly, many objects don't bother at all eg the repr of a class or function could yield the source representation thereof, but don't, because there's little use case for it and it'd be more annoying than useful.并且“如果可能的话”被非常松散和弱地解释,许多对象根本不会打扰例如类或函数的repr可以产生其源表示,但不要,因为它几乎没有用例并且它会比有用更烦人。

However, if there is a class having __slots__ , I find it hard to imagine how to implement this.但是,如果有一个具有__slots__的类,我很难想象如何实现它。 This is because when using __slots__ , some of the attributes in slots may be initialised and have values, others probably won't.这是因为在使用__slots__ ,插槽中的某些属性可能会被初始化并具有值,而其他的可能不会。

Certainly not.当然不是。 I've never written a class with slots where not all slots were filled all the time.我从来没有写过一个带有插槽的类,其中并非所有的插槽都一直被填满。 Plus hasattr / getattr work just fine with slots.加上hasattr / getattr与插槽一起工作得很好。

Though I have to ask: are you cargo-culting __slots__ ?虽然我不得不问:你是在培养货物__slots__吗? Did somebody once tell you to use slots and now you're using them everywhere?有人曾经告诉你使用插槽,现在你到处都在使用它们吗?

slots are a memory optimisation tool, the point is for instance to need exactly one pointer per member (+ some object overhead) rather than the overhead of a dict instance (and its amortised reallocations). slot 是一种内存优化工具,例如,关键是每个成员只需要一个指针(+ 一些对象开销),而不是 dict 实例的开销(及其摊销的重新分配)。 It makes very little sense to use slots when you're generally not filling them, and even less to add __dict__ to your slots.当您通常不填充它们时使用插槽几乎没有意义,更不用说将__dict__添加到您的插槽中。

Not to mention recent Python 3 iterations have added various optimisations to instance-dicts making slots even less useful, at least as the number of attributes increase (on fairly large classes as of 3.6 we found less than 5% difference, though on small classes it's likely still significant).更不用说最近的 Python 3 迭代已经为实例字典添加了各种优化,这使得槽变得更没用,至少随着属性数量的增加(在 3.6 的相当大的类上,我们发现差异不到 5%,尽管在小类上它是可能仍然很重要)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM