repr()

作者: import_hello | 来源:发表于2018-12-05 11:25 被阅读0次

    转载须注明出处:简书@Orca_J35 | GitHub@orca-j35

    🔨 repr(obj, /)

    该方法会返回 obj 的标准(canonical)字符串表示形式——可供解释器读取的表示形式。

    对于大多数类型(包含大多数内置类型)来说,repr(obj) 返回的字符串应该像是一个有效的 Python 表达式,并且将该字符串传递给 evla() 后,可以创建一个具备相同值的对象(需给定恰当的环境),即 eval(repr(obj)) == obj

    如果 repr(obj) 无法返回一个有效的表达式,则应返回形如 <...some useful description...> 的字符串,其中会包含对象的类型的名称和附加信息(对象的名称和地址)。

    示例 - 观察 strrepr 的区别:

    >>> value = 'orca_j35\n'
    >>> str(value)
    'orca_j35\n'
    >>> repr(value)
    "'orca_j35\\n'"
    >>> eval(repr(value))
    'orca_j35\n'
    >>> eval(str(value))
    Traceback (most recent call last):
      File "<pyshell#21>", line 1, in <module>
        eval(str(value))
      File "<string>", line 1, in <module>
    NameError: name 'orca_j35' is not defined
    

    示例 - 无法返回有效表达式的情况:

    >>> class Student:
        def __init__(self,name):
            self.name = name
    
            
    >>> a = Student('Bob')
    >>> repr(a)
    '<__main__.Student object at 0x000001243768AEF0>'
    

    当我们通过 repr(obj) 获取对象的标准字符串表示形式时,实际上在 repr() 内部会调用 type(obj).__repr__(obj) 来获取对象的字符串表示形式。因此,可通过覆写类中的 __repr__() 方法来控制 repr() 的返回值。

    示例 - 覆写类中的 __repr__ 方法:

    >>> class Cls:
        def __repr__(self):
            return 'Cls类的实例:{}'.format(super().__repr__())
    
    >>> repr(Cls())
    'Cls类的实例:<__main__.Cls object at 0x0000012437522FD0>'
    # 如没有覆写__str__,同样会调用__repr__
    >>> str(Cls())
    'Cls类的实例:<__main__.Cls object at 0x00000124375C89E8>'
    

    示例 - 如果 __repr____str__ 相同,可直接写作 __repr__ = __str__

    class Student(object):
        def __init__(self, name):
            self.name = name
        def __str__(self):
            return 'Student object (name=%s)' % self.name
        __repr__ = __str__
    

    实现细节

    repr(obj) 会在内部调用 type(obj).__repr__(obj),从而使用类字典中的 __repr__() 方法来获取 obj 的标准字符串表示形式。也就是说在获取属性列表时,会跳过实例字典:

    class Cls:
        def __repr__(self):
            return super().__repr__()
    
    
    obj = Cls()
    from types import MethodType
    obj.__repr__ = MethodType(lambda self: '绑定到实例的__repr__方法', obj)
    print(repr(obj))
    '''Out:
    <__main__.Cls object at 0x000001F0D7A35470>
    '''
    

    如果仅考虑类和实例,这好像并没有什么意义,因为不会有人在实例字典中重新绑定 __repr__ 方法。但是,如果考虑到元类和类,这就很有意义了。类是元类的实例,当 obj 是一个类时,实际上需要调用元类中的 __repr__ 方法,此时我们便需要跳过类字典中 __repr__ 方法,使用元类中的同名方法。

    __repr__

    🔨 object.__repr__(self)

    该方法会返回对象的正式的(official)字符串表示形式(可供解释器读取的表示形式),其返回值必须是一个字符串对象。repr() 函数会在内部调用该方法。

    通常来说,__repr__ 返回的字符串应该像是一个有效的 Python 表达式,并且可用该字符串重新创建一个具备相同值的对象(需给定恰当的环境)。

    如果 __repr__ 无法返回一个有效的表达式,则应返回形如 <...some useful description...> 的字符串,其中会包含对象的类型的名称和附加信息(对象的名称和地址)。

    如果在某个类中覆写了 __repr__ ,但并没有覆写 __str__ 。那么当需要该类的实例的"非正式(informal)"的字符串表示形式时,也会调用 __repr__()

    通常会在调试时使用 __repr__ ,因此在描述对象时最重要的是提供丰富的信息和明确的含义。

    相关文章

      网友评论

          本文标题:repr()

          本文链接:https://www.haomeiwen.com/subject/aeccqqtx.html