gpt4 book ai didi

python - 在 super().__init__() 中访问父类(super class)的类属性

转载 作者:行者123 更新时间:2023-11-28 17:19:28 24 4
gpt4 key购买 nike

我有一个类 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 的实例继承父类(super class) Parent 中的所有实例属性,以及一些特定于子类的实例属性。(这就是我们使用继承的原因,不是吗?)所以我覆盖类属性 props 来定义特定于子的属性。

但它不起作用。

info = {
"name" : "Bob",
"col" : 5,
"line" : 10,
"type" : "Alien",
"foo" : 5,
"bar" : 10
}

c = Child(info)

实例c只有c.fooc.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__() 链来初始化一个子类实例?

最佳答案

您可以实现一个方法,从所有父类(super class)中收集 props 并在 __init__ 中使用它:

class Parent(object):
props = ("name", "col", "line", "type")

def __init__(self, **kwargs):
def __init__(self, kwargs):
initialize_properties(self, self.get_props(), kwargs)

def get_props(self):
return sum((getattr(k, 'props', ()) for k in self.__class__.mro()), ())

现在,您可以按照自己的方式简单地定义子类。您甚至不必重写构造函数:

class Child(Parent):
props = ("foo", "bar")

话虽如此,您声称您希望自己的类(class)人性化。如果有人阅读您的 child 类(class),他们会很高兴阅读:

class Child(Parent):
props = 'foo', 'bar', 'name', 'col', 'line', 'type'

并在一个地方提供所有类(class)的 Prop

关于python - 在 super().__init__() 中访问父类(super class)的类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42323329/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com