如何用多个参数重写Python类的构造函数?

2024-06-01 03:16:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类Foo,扩展类Bar。我想稍微覆盖一下Foo的constructor。我甚至不想知道巴尔的建筑师是什么。有办法吗?

如果你不明白,我是说:

class Bar:
   def __init__ (self, arg1=None, arg2=None, ... argN=None):
      ....


class Foo (Bar):
    #Here i just want add additional parameter to constructor, but don't want to know anything about Bar's other parameters (arg1, arg2..., argN)
    def __init__ (self, my_new_arg=None, ??? )
       self.new_arg = my_new_arg
       Bar.__init__(self, ??? )

有没有一种方法可以把一些短而优雅的东西代替???在这个密码里? (可能是args/kwargs的一些变体)


Tags: toselfnonenewfooinitdefarg
2条回答
class Parent(object):
    def __init__(self, a, b):
        print 'a', a
        print 'b', b

class Child(Parent):
    def __init__(self, c, d, *args, **kwargs):
        print 'c', c
        print 'd', d
        super(Child, self).__init__(*args, **kwargs)

test = Child(1,2,3,4)

输出:

c 1
d 2
a 3
b 4

@Acorn提出的*args, **kwds解决方案是一个良好的开端(尽管我对答案的*args部分有异议)。本文对这种方法进行了许多改进,如Python的Super Considered Super

不建议使用*args部分,因为它不允许您在层次结构中插入新类,并且它禁止子类与可能具有不兼容位置参数的其他类一起使用多重继承。**kwds方法工作得更好,因为它没有强制调用链的特定顺序。

另外请注意,在将当前方法的命名参数传递到链之前,可以使用命名参数将其从其余关键字参数中分离并移除:

class Bar(object):
   def __init__(self, arg1=None, arg2=None, argN=None):
       print arg1, arg2, argN

class Foo(Bar):
    def __init__(self, my_new_arg=None, **kwds):
       super(Foo, self).__init__(**kwds)
       self.new_arg = my_new_arg
       print my_new_arg

f = Foo(my_new_arg='x', arg2='y')

让每个方法去掉它需要的参数是很重要的,因为像object.__init__这样的父方法根本不需要参数。

最后一点,如果您要使用super,请确保您的顶级类是新样式的(即,它继承自object或其他一些内置类型)。

相关问题 更多 >