当前位置: 首页 > 面试题库 >

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

曹铭晨
2023-03-14
问题内容

因此,我遵循了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,但两者均失败。

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


问题答案:

有时两个类可能有一些相同的参数名称。在这种情况下,您无法将键值对从中弹出**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中的倒数第二个类。



 类似资料:
  • 该方案应做到以下几点: 当这是运行时,所有的输出是“请输入你的心率:”。一旦我输入一个整数,程序就结束了。做错了什么?

  • 您可以看到,我正在将“that”作为参数传递给PrintInfo。如果没有“that”参数,“info”将打印为“undefined”。像下面的例子一样,当从“子类”的对象调用此函数时,“this.info”是未定义的。 如何在javascript中重写和调用超类的方法,使函数能够访问类的实例变量?

  • 问题内容: 我想编写一个接受参数的函数,该参数可以是序列或单个值。值的类型为str,int等,但我 不 希望将其限制为硬编码列表。换句话说,我想知道参数X是一个序列还是必须转换为序列的对象,以避免以后出现特殊情况。我可以做 但是可能还有我不知道的其他序列类型,也没有通用的基类。 -N。 编辑 :请参阅下面的“答案”,了解其中大多数答案对我没有帮助的原因。也许您有更好的建议。 问题答案: 上述所有方

  • 问题内容: 这个想法是使用更少的连接和更好的性能。连接是否随时终止? 对于另一个问题,是否打开新连接? 问题答案: 不,多路复用器不会过期。没有GetDatabase不会打开新连接。basics.md涵盖了所有内容 -特别是: 从GetDatabase返回的对象是便宜的直通对象,不需要存储。

  • 我有一个使用jquery mobile的应用程序,它由几个html页面组成,每个页面中都有几个jquery页面元素。在桌面浏览器上,一切正常,但当我把它加载到我的android设备(运行2.3)上时,第一个页面看起来很好,但只要你点击一个链接(比如从index.html)- 那么,是否有正确的方法在不同的html页面之间移动呢?我没有得到任何浏览器错误,所以一切似乎都工作正常,但没有jqm的样式或

  • 问题内容: 我正在尝试对表单中的某些字段使用get_or_create,但尝试这样做时却出现500错误。 其中一行如下所示: 对于以上代码,我得到的错误是: 问题答案: 从文档get_or_create中: 说明: 要评估相似性的字段必须在外部提及。其余字段必须包含在中。如果发生CREATE事件,则会考虑所有字段。 看起来你需要返回一个元组,而不是单个变量,请执行以下操作: