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中: super(Q,cls).M1(cls)#从这里获取错误,但是我们可以在python 3中使用相同的语句,并且可以正常工作。我只是想知道python 2.7是否可以通过使用super()来调用父类实现的任何类似方法。
`
答案 0 :(得分:1)
将print语句修改为函数,这似乎可以在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
但是在Python2中失败,并显示错误
TypeError:未绑定方法M1()必须以Q实例作为第一个参数(而不是类型实例)调用
正像错误所言,因为M1
是一个实例方法,它的参数必须是一个实例,而不是一个类。您可以通过将M1
设置为静态并且不使用任何参数来解决此问题。
我怀疑这在Python3中是可行的,因为 super()
实现中的技巧可以支持方法内部的使用。通读建议中的standard library docs和this很有帮助。
这在Python3中有效,因为它没有断言第一个参数的类型-假定该值合适并且没有遇到错误。鸭子打字的例子。
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
在这两种情况下,Python2都有一个嵌入式断言,即实例方法的第一个参数必须为匹配类的实例类型。 Python3没有这个断言-它很高兴收到None
或type
类型,至少直到收到的任何参数失效为止。这是ducktyping的一个很好的例子。
因此Foo.bar
在Python3中可以使用,因为它实际上并不关心参数的值是什么-它没有使用它。但是,在Foo.boo
中,尝试递增AttributeError
实例属性时,它失败并显示Foo._bar
(因为实例属性在给定的参数中不存在)。