代码之家  ›  专栏  ›  技术社区  ›  Camion

super()和repr(super())有什么区别?

  •  2
  • Camion  · 技术社区  · 6 年前

    在python(3.5.2)中,我希望 repr(obj) 调用magic方法的函数 __repr__() 属于 obj 的班级。 然而,给他们两个打电话似乎不会产生相同的结果。有人能解释为什么吗?

    示例代码:

    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)))
    

    结果:

    >>> 
     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)
    >>> 
    
    3 回复  |  直到 6 年前
        1
  •  4
  •   ShadowRanger    6 年前

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

    def repr(obj):
        return type(obj).__repr__(obj)  # Call unbound function of class with instance as arg
    

    当你在期待的时候:

    def repr(obj):
        return obj.__repr__()  # Call bound method of instance
    

    这种行为是有意的;第一,为每个实例定制dunder方法没有什么意义;第二,禁止它允许在C级别使用更高效的代码(它有更快的方法来完成上面的说明性方法所做的事情)。

    相比之下, super().__repr__() 在上查找方法 超级的 实例 ,和 超级的 定义自定义 tp_getattro (大致相当于定义一个自定义 __getattribute__ 方法),这意味着在找到 代表 / __代表__ 而是通过自定义属性getter(执行超类委托)进行调度。

        2
  •  1
  •   juanpa.arrivillaga    6 年前

    如果你咨询 the docs ,你会看到的 super 返回一个代理对象,该对象根据方法解析顺序将方法调用委托给相应的类。

    所以 repr(super()) 获取代理对象的表示形式。而方法调用 super().__repr__() 提供下一个类按方法解析顺序定义的表示形式。

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

    my_object.__mro__[1]
    
        3
  •  0
  •   IanQ    6 年前

    super().__repr__() 你调用了超级对象的repr类 'haha'

    在第二个,你打电话给 super() . 做什么 超级() 输出? <super: <class 'child'>, <child object>> 所以你实际上是在某个类层次上调用repr