python - 在方法的开头或结尾调用 super() 有什么区别?

标签 python super

我正在尝试了解 super() 的工作原理。我了解它的作用,但我不了解幕后发生的事情的机制。我不太明白的一件事是:

class b(a):
    def __init__(self, name, age):
        self.name=name
        self.age=age
        super(b, self).__init__(name, age)

和:

class b(a):
    def __init__(self, name, age):
        super(b, self).__init__(name, age)
        self.name=name
        self.age=age

也许这两个例子没有区别,但我知道还有其他情况 super() 的位置很重要。例如,前几天我需要帮助的这个 Django 方法,我被指示将 super() 移动到 if 语句上方,而不是底部。我想知道为什么这很重要。

class Mymodel(models.Model):
    photo = models.ImageField(upload_to="...", blank=True)

def save(self, *args, **kwargs):
    image_resized = kwargs.pop('image_resized',False)
    super(Mymodel, self).save(*args, **kwargs)
    if self.photo and image_resized:
        basewidth = 300
        filename = self.get_source_filename()
                image = Image.open(filename)
        wpercent = (basewidth/float(image.size[0]))
        hsize = int((float(image.size[1])*float(wpercent)))
        img = image.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
        self.photo = img
        self.save(image_resized = True)

最佳答案

b(如果有的话)的两个版本之间的区别完全取决于父类(super class)(a)的作用。让我们举一个更简单、更清晰的例子:

class a(object):
    def __init__(self):
        self.foo = 23

class b1(a):
    def __init__(self, name, age):
        self.foo = 42
        super(b, self).__init__()

class b2(a):
    def __init__(self, name, age):
        super(b, self).__init__()
        self.foo = 42

Class b1 首先将 foo 设置为 42 —— 然后(实际上)调用 a.__init__,它将相同的属性重置为 23 . 因此,self.foob1.__init__ 之后最终值 23。

Class b2 首先(在实践中)调用 a.__init__,它将 foo 设置为 23——然后,它继续重置与 42 相同的属性。因此,self.foob2.__init__ 之后最终值 42。

我发现这种情况更简单、更清晰,因为它归结为对同一事物的两次不同值赋值——所以很直观的是,第二次赋值覆盖了第一次赋值的效果。因此,在子类做自己的事情之前调用父类(super class)的 __init__ 意味着子类可以覆盖父类(super class)中完成的部分或全部设置;在之后调用它,意思正好相反。

完全相同的推理适用于初始化操作,它比对 self 属性的简单赋值更微妙:它是关于哪个类,子类或父类(super class),来调整或否决由另一个(就两个初始化而言非常重要)。

在 OOP 中,更常见的是希望子类“覆盖”父类(super class),反之亦然;因此,调用父类(super class)的 __init__ 的正常时间恰好在子类的开始时——这更符合习惯。当需要更微妙的效果时,可以稍后调用父类(super class)的 __init__,但在那些“稍微异常”的情况下,它通常会帮助代码的读者添加注释来解释正在做什么以及为什么。 ..

关于python - 在方法的开头或结尾调用 super() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27826095/

相关文章:

java - 在 Java 中向上转换 "this"引用是否有意义?

java - 在Java中,我们如何知道构造函数中的super()何时完成?

java - java子类的私有(private)final字段可以在 super 构造函数完成之前初始化吗?

python - ElementTree: list.remove(x): x 不在列表中

python - 过滤后的 Numpy 数组更改维数

python - 如何用 2 * 3 block 占据 10 x 10 block ,并且不让其他人推另一个 2 * 3 block

java - 什么是 PECS(生产者扩展消费者 super )?

javascript - ES6 (Babel) - 不能在类定义之外调用扩展类的 super.methodName

python - python中的压缩(存档)旧日志文件

python - 用于网络分析屏幕的Django设计模式需要很长时间才能计算出来