派生类的Python构造函数
class baseClass():
def __init__(self,mark,name):
self.mark = mark
self.name = name
class derivedClass(baseClass):
b1 = derivedClass(name='Jibin')
print b1.name
这是我最开始的代码,运行得很好。
(注意:我没有权限访问 baseClass
)
但后来我需要给 derivedClass
传递一个额外的属性 rank
,所以我把代码改成了这样。
class baseClass():
def __init__(self,mark,name):
self.mark = mark
self.name = name
class derivedClass(baseClass):
def __init__(self,rank):
self.rank = rank
b1 = derivedClass(name='Jibin')
print b1.name
这导致了一个错误 __init__() got an unexpected keyword argument 'name'
这个错误是可以预料的,因为 derivedClass
的 __init__
方法并没有 name
这个参数。
我不想在 derivedClass
的 __init__
方法中添加一个额外的 name
参数,因为实际上 baseClass
有十个参数,而不是两个(mark, name),如果我把所有这些都作为额外参数传给 derivedClass
,那样会让参数列表变得很乱。
注意:我知道可以通过 baseClass.__init__(self)
或 super(derivedClass, self).__init__()
来初始化 baseClass
。
4 个回答
这个博客讲述了如何解决这类问题。解决方法是让 base
和 derived
在它们的 __init__
方法中都接受一个 **kwargs
参数,并把这个参数传递给 super
的调用。
derivedClass
实际上并不是从 baseClass
继承来的。在 Python 中,要创建一个子类,你必须在类定义时指定父类,像这样:
class DerivedClass(BaseClass):
pass
DerivedClass
现在可以使用 BaseClass
的方法,包括 __init__()
方法。如果你没有重写某个方法,那么在子类中调用这个方法时,实际上是调用了父类中定义的那个方法。
所以,如果你想让 DerivedClass(name='Jibin')
这样使用,你需要提供一个特别的 init():
class BaseClass(object):
def __init__(self, mark, name):
self.mark = mark
self.name = name
class DerivedClass(BaseClass):
def __init__(self, mark, name, rank):
BaseClass.__init__(self, mark, name)
self.rank = rank
现在,你还想让 DerivedClass()
支持额外的关键字参数,而不需要明确地添加它们。实现这个的一个方法是将所有的 kwargs
赋值给实例属性,像这样:
class BaseClass(object):
def __init__(self, mark, name, **kwargs):
self.mark = mark
self.name = name
self.__dict__.update(kwargs)
不过,我并不建议你真的这么做。盲目地设置属性可能会在将来引入一些微妙的错误(比如不小心用同名的关键字参数替换了一个方法)。
也许你可以试试这样的做法:
class BaseClass(object):
def __init__(self, mark=None, name=None): # you're using named parameters, declare them as named one.
self.mark = mark
self.name = name
class DerivedClass(BaseClass): # don't forget to declare inheritance
def __init__(self, rank=None, *args, **kwargs): # in args, kwargs, there will be all parameters you don't care, but needed for baseClass
super(DerivedClass, self).__init__(*args, **kwargs)
self.rank = rank
b1 = DerivedClass(name='Jibin')
print b1.name