试图找出本身是类的类属性的类继承。这就是我要做的事情:
class foo:
hello = None
world = None
def __init__(self, **kwargs):
for k,v in kwargs.items():
if hasattr(self, k):
setattr(self, k, v)
else:
raise AttributeError(f'class foo has no attribute {k}')
class foo2:
hi = None
earth = None
def __init__(self, **kwargs):
for k,v in kwargs.items():
if hasattr(self, k):
setattr(self, k, v)
else:
raise AttributeError(f'class foo has no attribute {k}')
class bar:
foo_attr = foo(hello=1, world=2)
foo2_attr = foo2(hi=3, earth=4)
class bar2(bar):
def __init__(self):
super().__init__()
所以我有2个基类(foo and foo2
),每个基类有2个属性(分别为hello
& world
,hi
和earth
。
我有另一个基类(bar
),里面有类属性,包含foo
和foo2
的默认值。
更新(包含问题):
最后,我有bar2
,它是bar
的子类。如何更改自身类的子类属性的值? (比如bar2中foo_attr的hello属性)
我试图为bar
设置一个默认值,但我希望能够在子类化时为bar中的每个类属性设置不同的属性。这样,我可以像这样创建一堆bar的子类:
一个bar2
,默认属性除了foo2.earth,我设置为20.这意味着bar2有:
然后仍然可以创建一个bar3,假设foo()和foo2()的默认属性除了foo.hello,我可能想要设置为30然后添加一个新的属性say&#34 ;哎呀"
我该怎么做?
答案 0 :(得分:0)
看起来您想为bar
和bar2
创建一个显式构造函数,以便您可以选择属性:
class bar:
def __init__(self, hello=1, world=2, hi=3, earth=4)
self.foo_attr = foo(hello=hello, world=world)
self.foo2_attr = foo2(hi=hi, earth=earth)
class bar2:
def __init__(self)
bar.__init__(self, earth=20)
您仍然可以在新类中添加新属性。
答案 1 :(得分:0)
我认为您需要将功能放入foo
和foo2
,如果这些功能继承自具有该功能的公共超类,则您的重复次数会减少。下面的脚本可以工作(我必须删除' f'字符串,因为我已经陷入了蟒蛇3.5的黑暗时代)。仍然有一些工作实现了bar子类,但相对合理。
import copy
class Fooinator:
def __init__(self, **kwargs):
badniks = self._update_instance(**kwargs)
if badniks:
raise AttributeError('class foo has no attributes {}'.format(badniks))
def _update_instance(self, **kwargs):
"""Update self for variables defined at the class level returning
names of variables not used by this class. """
badniks = []
for k,v in kwargs.items():
if hasattr(self, k):
setattr(self, k, v)
else:
badniks.append(k)
return badniks
def opt_clone(self, **kwargs):
"""Given keyword arguments, clone a copy of self if any of them are
used by this class, else return self."""
for k in kwargs:
if hasattr(self, k):
me_2 = copy.copy(self)
me_2._update_instance(**kwargs)
return me_2
return self
class foo(Fooinator):
hello = None
world = None
class foo2(Fooinator):
hi = None
earth = None
class bar:
foo_attr = foo(hello=1, world=2)
foo2_attr = foo2(hi=3, earth=4)
class bar2(bar):
foo2_attr = bar.foo2_attr.opt_clone(earth=20)
b = bar2()
print(b.foo_attr.hello, b.foo_attr.world, b.foo2_attr.hi, b.foo2_attr.earth)