gpt4 book ai didi

python - Python-2.x 中的 super() 是否损坏?

转载 作者:IT老高 更新时间:2023-10-28 21:34:41 24 4
gpt4 key购买 nike

人们常说super应该是 avoided在 Python 2 中。我在 Python 2 中使用 super 时发现,除非我提供所有参数,例如示例:

super(ThisClass, self).some_func(*args, **kwargs)

在我看来这违背了使用 super() 的目的,它既不简洁,也不比 TheBaseClass.some_func(self, *args, **kwargs)。对于大多数目的,方法解析顺序是一个遥远的童话。

  • 除了 2.7 is the last major release到 Python 2,为什么 super 在 Python 2 中仍然存在问题?
  • Python 3's super 如何以及为什么改变了吗?有什么注意事项吗?
  • 以后何时以及为什么应该使用 super

最佳答案

super() 没有被破坏——它只是不应该被视为调用基类方法的标准方式。这在 Python 3.x 中没有改变。唯一改变的是,在 self 是当前函数的第一个参数和 的标准情况下,您不需要传递参数 self, cls >cls 是当前正在定义的类。

关于您何时实际使用 super() 的问题,我的回答是:几乎没有。我个人尽量避免那种会使 super() 有用的多重继承。

编辑:我曾经遇到的现实生活中的一个例子:我有一些定义了 run() 方法的类,其中一些具有基类。我使用 super() 来调用继承的构造函数——我认为这无关紧要,因为我只使用单继承:

class A(object):
def __init__(self, i):
self.i = i
def run(self, value):
return self.i * value

class B(A):
def __init__(self, i, j):
super(B, self).__init__(i)
self.j = j
def run(self, value):
return super(B, self).run(value) + self.j

想象一下有几个这样的类,都有各自的构造函数原型(prototype),并且都有相同的run()接口(interface)。

现在我想为所有这些类添加一些额外的功能,比如日志记录。附加功能需要在所有这些类上定义一个附加方法,例如 info()。我不想侵入原始类,而是定义第二组继承自原始类的类,添加 info() 方法并从提供实际日志记录的混合中继承。现在,我不能再在构造函数中使用 super() 了,所以我使用了直接调用:

class Logger(object):
def __init__(self, name):
self.name = name
def run_logged(self, value):
print "Running", self.name, "with info", self.info()
return self.run(value)

class BLogged(B, Logger):
def __init__(self, i, j):
B.__init__(self, i, j)
Logger.__init__("B")
def info(self):
return 42

这里的东西停止工作。基类构造函数中的super()调用突然调用Logger.__init__()BLogged对此无能为力。除了删除 B 本身中的 super() 调用之外,实际上没有办法使这项工作。

[另一个编辑:从此处和其他答案下方的所有评论来看,我似乎没有表达我的观点。以下是如何使用 super() 使此代码工作:

class A(object):
def __init__(self, i, **kwargs):
super(A, self).__init__(**kwargs)
self.i = i
def run(self, value):
return self.i * value

class B(A):
def __init__(self, j, **kwargs):
super(B, self).__init__(**kwargs)
self.j = j
def run(self, value):
return super(B, self).run(value) + self.j

class Logger(object):
def __init__(self, name, **kwargs):
super(Logger,self).__init__(**kwargs)
self.name = name
def run_logged(self, value):
print "Running", self.name, "with info", self.info()
return self.run(value)

class BLogged(B, Logger):
def __init__(self, **kwargs):
super(BLogged, self).__init__(name="B", **kwargs)
def info(self):
return 42

b = BLogged(i=3, j=4)

将此与使用显式父类(super class)调用进行比较。你决定你喜欢哪个版本。]

这个和类似的故事是为什么我认为super() 不应该被认为是调用基类方法的标准方式。这并不意味着 super() 坏了。

关于python - Python-2.x 中的 super() 是否损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5066315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com