在Python2.7中,我们可以从子类的类方法调用父类的实例方法吗?

在Python2.7中,我们可以从子类的类方法调用父类的实例方法吗?,python,python-2.7,Python,Python 2.7,在Python2中: super(Q,cls).M1(cls)#从这里得到错误,但是我们可以在Python3中使用相同的语句,它可以工作。我只是想知道Python2.7是否可以通过使用super()调用父类实现 `将print语句修改为函数,这似乎在Python 3.7中运行得很好 In Python 2 class P(object): def M1(self): print 'inside P class M1())' class Q(P): def M1(self): print

在Python2中: super(Q,cls).M1(cls)#从这里得到错误,但是我们可以在Python3中使用相同的语句,它可以工作。我只是想知道Python2.7是否可以通过使用super()调用父类实现


`

将print语句修改为函数,这似乎在Python 3.7中运行得很好

In Python 2
class P(object):
  def M1(self): print 'inside P class M1())'
class Q(P):
  def M1(self): print 'inside Q class M1()'
  @classmethod
  def M2(cls):
    super(Q,cls).M1(cls)
s = Q()
s.M2()
----------------In Python3-------
class P(object):
   def M1(self): print ('inside M1 Method of P class')
class Q(P):
  @classmethod
  def M2(cls):
    super().M1(cls) or super(Q,cls)M1(cls)
s = Q()
s.M2()
但在Python2中失败并出现错误

TypeError:必须以Q实例作为第一个参数调用未绑定的方法M1()(改为获取类型实例)

正如错误所说,因为
M1
是一个实例方法,所以它的参数必须是实例,而不是类。您可以通过使
M1
为静态且不带任何参数来解决此问题

我怀疑这在Python3中是有效的,因为
super()
实现中使用了一些技巧来支持方法内部的使用。通读这篇文章和推荐的文章很有帮助

这在Python3中起作用,因为它不断言第一个参数的类型——它假定该值是合适的,并且不会出错。duck类型的一个示例

编辑,对Python3行为更一般 OP看到的错误实际上不是由于
super()
,而是由于Python3处理实例方法的方式不同于Python2。一个示例类可以是

Python 3.7.1 (default, Dec 10 2018, 22:54:23) [MSC v.1915 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: class P(object):
   ...:     def M1(self): print('inside P')
   ...: class Q(P):
   ...:     def M1(self): print('inside Q')
   ...:     @classmethod
   ...:     def M2(cls):
   ...:         super(Q, cls).M1(cls)
   ...:

In [2]: s = Q()

In [3]: s.M2()
inside P
在这两种情况下,Python2都有一个嵌入式断言,即实例方法的第一个参数必须是匹配类的实例类型。Python3没有这个断言——它很乐意接收
None
type
类型,至少在它接收到的任何参数失败之前是这样。这是一个很好的例子


因此,
Foo.bar
在Python3中工作,因为它实际上并不关心参数的值是什么——它不使用它。但是,在
Foo.boo
中,当尝试递增
Foo.\u bar
实例属性时,它会失败,并出现
AttributeError
(因为该实例属性在给定的参数中不存在)。

我很确定这不会在Python 3中运行。请添加错误(完全回溯)对于你的问题也是如此。如果你想让你的代码与Python 3兼容(正如你在问题中所建议的那样),至少在你的示例中使用print函数而不是print语句。class P(object):def M1(self):print('inside M1 Method of P class')class Q(P):@classmethod def M2(cls):super().M1(cls)s=Q()s.M2()所以我们不能在Python2.7中从类方法调用实例方法吗?但是在python3中,它工作得很好。在Python2.7中,实例方法的
self
参数必须是实例,否则会得到
TypeError
。如果您查看Python2中
P.M1
的类型,它是
unbound方法P.M1
,但在Python3中它是一个命名空间范围的函数。因此,在Python3中,它似乎推断
P.M1
实际上是静态的。我更新了我的答案,补充了关于Python3行为的信息。
>>> class Foo(object):
>>>     def __init__(self):
>>>         self._bar = 0
>>>     def bar(self): 
>>>         print('baz')
>>>     def boo(self):
>>>         self._bar+=1
>>>         print(self._bar)
>>> f = Foo()
>>> Foo.bar(Foo)  # fine in Python3, TypeError in Python2
>>> Foo.bar(None)  # fine in Python3, TypeError in Python2
>>> f.bar()  # fine in both
baz
>>> Foo.boo(Foo)  # AttributeError in Python3, TypeError in Python2