首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.__repr__()和repr(super())有什么区别?

.__repr__()和repr(super())有什么区别?
EN

Stack Overflow用户
提问于 2018-11-24 09:37:15
回答 3查看 1.8K关注 0票数 7

在python (3.5.2)中,我期望repr(obj)函数调用obj类的魔法方法__repr__()。然而,调用这两个函数似乎不会产生相同的结果。有谁能解释一下原因吗?

示例代码:

代码语言:javascript
复制
class parent:

    def __init__(self):
        self.a = "haha"

    def __repr__(self):
        return repr(self.a)

class child(parent):
    def __init__(self):
        super().__init__()
        self.b="bebe"

    def __repr__(self):
        return "("+super().__repr__()+", "+repr(super())+", "+self.b+")"

    def print1(self):
        print("super().__repr__() returns:", super().__repr__())
        print("repr(super()) returns:", repr(super()))
        print("plom(super()).__repr__() returns:", plom(super()).__repr__())
        print("repr(plom(super())) returns:", repr(plom(super())))

def plom(var):
    return var

t=child()
print(t.__repr__())
print(repr(t))
print('-----')
t.print1()
print('-----')
print(plom(t).__repr__())
print(repr(plom(t)))

结果:

代码语言:javascript
复制
>>> 
 RESTART: test super.py 
('haha', <super: <class 'child'>, <child object>>, bebe)
('haha', <super: <class 'child'>, <child object>>, bebe)
-----
super().__repr__() returns: 'haha'
repr(super()) returns: <super: <class 'child'>, <child object>>
plom(super()).__repr__() returns: 'haha'
repr(plom(super())) returns: <super: <class 'child'>, <child object>>
-----
('haha', <super: <class 'child'>, <child object>>, bebe)
('haha', <super: <class 'child'>, <child object>>, bebe)
>>> 
EN

回答 3

Stack Overflow用户

发布于 2018-11-24 10:36:35

调用repr(super())直接访问super类上的__repr__ (从技术上讲,这是定义super类型的C PyTypeObject结构的tp_repr )。大多数特殊的dunder方法在隐式调用时都是这样的(而不是显式地将它们作为方法调用)。repr(x)不等同于x.__repr__()。您可以将repr定义为:

代码语言:javascript
复制
def repr(obj):
    return type(obj).__repr__(obj)  # Call unbound function of class with instance as arg

当你期待它的时候:

代码语言:javascript
复制
def repr(obj):
    return obj.__repr__()  # Call bound method of instance

这种行为是有意为之的;首先,对每个实例定制Dunder方法意义不大,其次,禁止它允许在C级别上编写更有效的代码(它有更快的方式来完成上面说明性方法所做的事情)。

相比之下,super().__repr__()super实例上查找方法,而super定义一个自定义tp_getattro (大致相当于定义一个自定义__getattribute__方法),这意味着在实例上的查找在找到类的tp_repr/__repr__之前被拦截,而是通过自定义属性getter (执行超类委托)分派。

票数 7
EN

Stack Overflow用户

发布于 2018-11-24 10:37:13

如果您查阅 the docs,您将看到super返回一个代理对象,该对象根据方法解析顺序将方法调用委托给适当的类。

因此,repr(super())为您提供了代理对象的表示。而方法调用super().__repr__()按照方法解析顺序给出了下一个类定义的表示。

如果您想要超类本身,请尝试

代码语言:javascript
复制
my_object.__mro__[1]
票数 1
EN

Stack Overflow用户

发布于 2018-11-24 10:09:11

super().__repr__()中,您将调用超级对象的repr类,因此您将获得'haha'

在第二个示例中,您将调用super()的repr。super()的输出是什么?<super: <class 'child'>, <child object>>所以您实际上是在某个类层次结构上调用repr

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53454458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档