【发布时间】:2017-02-19 03:31:54
【问题描述】:
我有一个类Parent 有很多实例属性,我总是传递一个dict 来初始化一个实例。像这样:
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__() 链来初始化子类实例时,有什么方法可以检测当前类并访问其类属性?
【问题讨论】:
-
这似乎需要做很多工作来避免
this.property_name = value“对于每个属性,因为代码会很长”...
标签: python class inheritance