我试图提出一种方法,允许在实例化时指定任意数量的类属性,这与字典非常相似。理想的用例:
>>> instance = BlankStruct(spam=0, eggs=1)
>>> instance.spam
0
>>> instance.eggs
1
其中BlankStruct定义为:
class BlankStruct(Specifiable):
@Specifiable.specifiable
def __init__(self, **kwargs):
pass
我本来打算使用父类装饰器,但是却迷失了是使用实例方法,类方法还是静态方法(或者可能不使用上述任何一种!)。到目前为止,这是我想出的最好的方法,但是问题是属性是应用于类而不是实例:
class Specifiable:
@classmethod
def specifiable(cls, constructor):
def constructor_wrapper(*args, **kwargs):
constructor(*args, **kwargs)
cls.set_attrs(**kwargs)
return constructor_wrapper
@classmethod
def set_attrs(cls, **kwargs):
for key in kwargs:
setattr(cls, key, kwargs[key])
如何进行此类家长班?
答案 0 :(得分:1)
是的,您可以执行以下操作,但是我不建议这样做,因为这明显违反了显式优于隐式原理:
class BlankStruct:
def __init__(self, **attrs):
self.__dict__.update(**attrs)
def __getattr__(self, attr):
return self.__dict__.get(attr, None)
f = BlankStruct(spam=0, eggs=1)
here可以提供更完整的答复,并启发了这个答案。
根据您希望班级拥有的属性,我建议明确。否则,您将剩下一类具有高度可变性的类,这可能会降低其有用性。
答案 1 :(得分:0)
我相信您可以在没有装饰器的情况下做到这一点:
class Specifiable:
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
class BlankStruct(Specifiable):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Do other stuff.