使用继承编写 __repr__ 函数的正确方法

Correct way to write __repr__ function with inheritance

我正在尝试 OOP python,但我不确定 __repr__ 函数继承。由于父 class 函数如下所示:

def __repr__(self):
    '''Returns representation of the object'''
    return("{}({!r})".format("Class name", self._param))

我想知道使用像下面这样的通用方法(也可能适合儿童 classes)是否更好:

def __repr__(self):
    '''Returns representation of the object'''
    return("{}({!r})".format(self.__class__.__name__, self._param))

或者如果在每个 class.

中覆盖函数是一个好习惯

此外,请忽略编码部分,因为我将其放在后面。

是的 - - 它不仅仅是 "ok",而且它在几乎每个项目和 class 层次结构中都比较实用。

实际上,这几乎是一个完美的"text book example"何时使用class继承,只是让superclasses中的代码被重用。

那么 __repr__ 在 Python 的数据模型中有特殊的含义:

object.__repr__(self)

Called by the repr() built-in function to compute the “official” string representation of an 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. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an “informal” string representation of instances of that class is required.

This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.

这意味着 __repr__ 返回的字符串应该可用于创建另一个类似的对象。所以 __repr__ 经常 需要覆盖的东西,不是因为 __class__.__name__ 而是因为必须在表示中捕获“状态”。

class A(object):
    def __init__(self, param):
        self._param = param

    def __repr__(self):
        '''Returns representation of the object'''
        return("{}({!r})".format(self.__class__.__name__, self._param))

那么在为 __init__ 添加参数时绝对应该覆盖 __repr__:

class B(A):
    def __init__(self, param1, param2):
        self._param = param1
        self._param2 = param2

    def __repr__(self):
        '''Returns representation of the object'''
        return("{}({!r})".format(self.__class__.__name__, self._param, self._param2))

但是如果 superclass 的 __repr__ 仍然 准确地 “描述” subclass 那么就没有必要重载__repr__:

class B(A):
     pass

然而,使用 self.__class__.__name__ 而不是对 class 名称进行硬编码始终是一个不错的选择,以防万一您或其他人子class使用它。