为什么Python 2的`super`需要显式的类和自我参数?(Why does Python 2's `super` require explicit class and self arg

编程入门 行业动态 更新时间:2024-10-28 05:27:07
为什么Python 2的`super`需要显式的类和自我参数?(Why does Python 2's `super` require explicit class and self arguments?)

这个Python 2示例 :

class LoggingDict(dict):
    # Simple example of extending a builtin class
    def __setitem__(self, key, value):
        logging.info('Setting %r to %r' % (key, value))
        super(LoggingDict, self).__setitem__(key, value)
 

这个Python 3的例子 :

class LoggingDict(dict):
    # Simple example of extending a builtin class
    def __setitem__(self, key, value):
        logging.info('Setting %r to %r' % (key, value))
        super().__setitem__(key, value)
 

说明了Python 2的super需要显式类和self参数的事实(但Python 3没有)。 这是为什么? 这似乎是一个恼人的限制。

This Python 2 example:

class LoggingDict(dict):
    # Simple example of extending a builtin class
    def __setitem__(self, key, value):
        logging.info('Setting %r to %r' % (key, value))
        super(LoggingDict, self).__setitem__(key, value)
 

and this Python 3 example:

class LoggingDict(dict):
    # Simple example of extending a builtin class
    def __setitem__(self, key, value):
        logging.info('Setting %r to %r' % (key, value))
        super().__setitem__(key, value)
 

illustrate the fact that Python 2's super requires explicit class and self arguments (but Python 3's doesnt). Why is that? It seems like an irritating limitation.

最满意答案

AKS评论中的链接提供了答案:

让我们说在Python 2的例子中,我认为“我不喜欢那个显式的类引用。如果我更改类的名称或移动此代码并忘记更新它会怎么样?”。 让我们说,我想,我会用self.__class__替换显式类名,并写道:

class LoggingDict(dict):
    # Simple example of extending a builtin class
    def __setitem__(self, key, value):
        logging.info('Setting %r to %r' % (key, value))
        super(self.__class__, self).__setitem__(key, value)
 

现在我创建了一个名为LoggingDict SpecialisedLoggingDict的子类(它不会覆盖__setitem__ ),实例化它并在其上调用__setitem__ 。

现在self指的是SpecialisedLoggingDict一个实例,所以super返回LoggingDict ,然后我们直接回到LoggingDict.__setitem__ ,进入无限递归。

关键点在于Python 2中的方法并不真正知道它所定义的类,它只知道调用它的实例的类 。 Python 3 执行编译时“魔术” ,向函数添加__class__单元格,以便在没有显式类引用的情况下使用super() 。

The link in AKS' comment provides the answer here:

Lets say in the Python 2 example I thought "I don't like that explicit class reference. What if I change the name of the class or move this code and forget to update it?". Lets say I thought, a-ha, I'll replace the explicit class name with self.__class__ and wrote:

class LoggingDict(dict):
    # Simple example of extending a builtin class
    def __setitem__(self, key, value):
        logging.info('Setting %r to %r' % (key, value))
        super(self.__class__, self).__setitem__(key, value)
 

Now I create a subclass called SpecialisedLoggingDict of LoggingDict (which doesn't override __setitem__), instantiate it and call __setitem__ on it.

Now self refers to an instance of SpecialisedLoggingDict, so the super returns LoggingDict, and we go straight back into LoggingDict.__setitem__, entering infinite recursion.

The essential point is that in Python 2 a method doesn't really know which class it was defined in, it only knows the class of the instance on which it's being called. Python 3 does compile-time "magic", adding a __class__ cell to functions so that super() can be used without the explicit class reference.

更多推荐

本文发布于:2023-07-26 05:15:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1271386.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自我   参数   super   Python   arguments

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!