如何使用构造函数关键字参数指定Python类属性

时间:2018-10-31 20:07:58

标签: python class decorator

我试图提出一种方法,允许在实例化时指定任意数量的类属性,这与字典非常相似。理想的用例:

>>> 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])

如何进行此类家长班?

2 个答案:

答案 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.