我有一个类Parent
,有许多实例属性,我总是通过传递一个字典
来初始化一个实例。就像这样:
info = {
"name" : "Bob",
"col" : 5,
"line" : 10,
"type" : "Alien"
}
p = Parent(info)
在__init__
方法中,我不想为每个属性编写this.property_name = value
的代码,因为代码会很长。例如:
class Parent(object):
def __init__(self, kwargs):
this.name = kwargs.get("name")
this.col = kwargs.get("col")
this.line = kwargs.get("line")
this.type = kwargs.get("type")
所以我想使用一个函数来迭代 dict
并设置这些实例属性。这是我编写的函数:
def initialize_properties(instance, names, kwargs):
for name in names:
setattr(instance, name, kwargs.get(name))
看起来我需要将属性名列表 names
存储在某个地方,我决定将其作为类属性存储,因为我希望我的类是 用户友好的(当有人阅读类定义时,他知道这个类具有哪些实例属性)。因此,我将我的类定义更改如下:
class Parent(object):
props = ("name", "col", "line", "type")
def __init__(self, kwargs):
initialize_properties(self, self.props, kwargs)
当不考虑继承时,这个功能可以正常工作。但是当我继承Parent
时就会出现问题:
class Child(Parent):
props = ("foo", "bar")
def __init__(self, kwargs):
super().__init__(kwargs)
initialize_properties(self, self.props, kwargs)
我希望
Child
的实例能够继承超类Parent
中的所有实例属性,并且还有一些特定于子类的实例属性。(这就是我们使用继承的原因,不是吗?) 所以,我重写了类属性props
来定义子类特定的属性。
但是它并没有起作用。
info = {
"name" : "Bob",
"col" : 5,
"line" : 10,
"type" : "Alien",
"foo" : 5,
"bar" : 10
}
c = Child(info)
实例c
只定义并设置了c.foo
和c.bar
,而c.name
未定义。
经过一番查找,我发现当通过super()
函数调用Parent.__init__(self, kwargs)
时,传递的self
参数是Child
类的,因此self.props
会被解析为Child.props
。
如果我想要在Parent.props
中设置实例属性,则必须在Parent.__init__(self, kwargs)
中显式使用Parent.props
,即:
class Parent(object):
props = ("name", "col", "line", "type")
def __init__(self, kwargs):
initialize_properties(self, Parent.props, kwargs)
这样可以解决问题,但我认为它不太“干净”,因为您必须硬编码类名 Parent
。
我的问题是:在调用一系列super().__init__()
来初始化子类实例时,是否有办法检测当前类并访问其类属性?