简体   繁体   English

我们可以在python 2.7中从子类的类方法中调用父类的实例方法吗?

[英]Can we call instance method of parent class from class method of child class in python 2.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()

In Python2: super(Q,cls).M1(cls)#Getting error from here,But we can use same statement in python 3 and it works .在 Python2 中: super(Q,cls).M1(cls)#Getting error from here,但我们可以在 python 3 中使用相同的语句并且它有效。 I just wondering whether python 2.7 can have any similar way to call parent class implementation by using super() or not .我只是想知道 python 2.7 是否可以通过使用 super() 或不使用任何类似的方式来调用父类实现。

` `

Modifying the print statements to functions, this seems to run happily inside of Python 3.7将打印语句修改为函数,这似乎在 Python 3.7 中运行良好

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

But fails in Python2 with the error但在 Python2 中失败并出现错误

TypeError: unbound method M1() must be called with Q instance as first argument (got type instance instead)类型错误:必须使用 Q 实例作为第一个参数调用未绑定的方法 M1()(改为获取类型实例)

Exactly as the error says, because M1 is an instance method its argument must be an instance, not a class.正如错误所说,因为M1是一个实例方法,它的参数必须是一个实例,而不是一个类。 You can get around this by making M1 static and take no arguments.您可以通过将M1静态并且不接受任何参数来解决此问题。

I suspect this works in Python3 because of tricks inside the implementation of super() to support usage inside of methods.我怀疑这在 Python3 中是有效的,因为super()的实现中有一些技巧来支持方法内部的使用。 Reading through the standard library docs and this recommended post were helpful.通读标准库文档这篇推荐的文章很有帮助。

This works in Python3 because it doesn't assert the type of the first argument -- it assumes the value is suitable and doesn't hit an error.这在 Python3 中有效,因为它不会断言第一个参数的类型——它假设该值是合适的并且不会出错。 An example of duck typing.鸭子打字的一个例子。

Edit, more general to Python 3 behavior编辑,更通用的 Python 3 行为

The error OP is seeing is not actually due to super() but due to how Python 3 handles instance methods differently than Python 2. An example class could be OP 看到的错误实际上并不是由于super()而是由于 Python 3 处理实例方法的方式与 Python 2 不同。示例类可能是

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

In both cases for, Python2 has an embedded assertion that the first argument of an instance method must be an instance type of the matching class.在这两种情况下,Python2 都有一个嵌入式断言,即实例方法的第一个参数必须是匹配类的实例类型。 Python3 does not have this assertion for -- it's happy receiving None or a type type, at least until whatever argument it received fails to work. Python3 没有这个断言——它很高兴接收Nonetype类型,至少在它接收到的任何参数无法工作之前。 This is a great example of ducktyping .这是ducktyping 的一个很好的例子。

So Foo.bar works in Python3 because it doesn't actually care what the value of the argument is -- it doesn't use it.所以Foo.barFoo.bar工作,因为它实际上并不关心参数的值是什么——它不使用它。 In Foo.boo , however, it fails with an AttributeError when trying to increment the Foo._bar instance property (because that instance property doesn't exist in the argument it was given).但是,在Foo.boo ,当尝试增加Foo._bar实例AttributeError时,它会失败并显示AttributeError (因为该实例属性不存在于给定的参数中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM