小编典典

正确的使用超级方法(参数传递)

python

因此,我遵循了Python的《超级被认为有害》,并去测试他的例子。

但是,示例1-3应该显示正确的调用方式,super当处理__init__期望使用不同参数的方法时,平坦化不起作用。

这是我得到的:

~ $ python example1-3.py 
MRO: ['E', 'C', 'A', 'D', 'B', 'object']
E arg= 10
C arg= 10
A
D arg= 10
B
Traceback (most recent call last):
  File "Download/example1-3.py", line 27, in <module>
    E(arg=10)
  File "Download/example1-3.py", line 24, in __init__
    super(E, self).__init__(arg, *args, **kwargs)
  File "Download/example1-3.py", line 14, in __init__
    super(C, self).__init__(arg, *args, **kwargs)
  File "Download/example1-3.py", line 4, in __init__
    super(A, self).__init__(*args, **kwargs)
  File "Download/example1-3.py", line 19, in __init__
    super(D, self).__init__(arg, *args, **kwargs)
  File "Download/example1-3.py", line 9, in __init__
    super(B, self).__init__(*args, **kwargs)
TypeError: object.__init__() takes no parameters

看来它object本身违反了文档中提到的最佳实践之一,即使用的方法super必须接受*args**kwargs

现在,很明显,奈特先生希望他的例子能奏效,这在最近的Python版本中是否有所改变?我检查了2.6和2.7,但两者均失败。

那么解决这个问题的正确方法是什么?


阅读 136

收藏
2020-12-20

共1个答案

小编典典

有时两个类可能有一些相同的参数名称。在这种情况下,您无法将键值对从中弹出**kwargs或从中删除*args。相反,您可以定义一个Base不同于object,吸收/忽略参数的类:

class Base(object):
    def __init__(self, *args, **kwargs): pass

class A(Base):
    def __init__(self, *args, **kwargs):
        print "A"
        super(A, self).__init__(*args, **kwargs)

class B(Base):
    def __init__(self, *args, **kwargs):
        print "B"
        super(B, self).__init__(*args, **kwargs)

class C(A):
    def __init__(self, arg, *args, **kwargs):
        print "C","arg=",arg
        super(C, self).__init__(arg, *args, **kwargs)

class D(B):
    def __init__(self, arg, *args, **kwargs):
        print "D", "arg=",arg
        super(D, self).__init__(arg, *args, **kwargs)

class E(C,D):
    def __init__(self, arg, *args, **kwargs):
        print "E", "arg=",arg
        super(E, self).__init__(arg, *args, **kwargs)

print "MRO:", [x.__name__ for x in E.__mro__]
E(10)

产量

MRO: ['E', 'C', 'A', 'D', 'B', 'Base', 'object']
E arg= 10
C arg= 10
A
D arg= 10
B

请注意,要使其正常工作,Base必须是MRO中的倒数第二个类。

2020-12-20