在Python 3中实例化具有未知数量属性的类的实例

时间:2014-10-16 03:14:01

标签: python oop

如何在不指定所有属性的默认值的情况下创建对象的实例(可能有很多,如20个)属性?

例如,假设我有

class Thing:
    def __init__(self, att1, att2, att3, etc....):
        self.att1 = att1
        self.att2 = att2
        self.att3 = att3
        etc

我可以说,

first_thing = Thing()
first_thing.att1 = 33

但是,如果我有30个属性,我不想为每个属性指定self.att = att。有办法摆脱这种局面吗?例如,让我们说后来我添加了一个属性,并且想要返回并将其添加到__init__函数,或者我不想在声明30个值时创建一个对象的实例 - 有这种方法吗?

3 个答案:

答案 0 :(得分:1)

  

有没有办法解决这个问题?

是的! Argument unpacking

例如:

class Thing:
    def __init__(self, *args):
        self.att1, self.att2, self.att3 = args

如果事实证明你有时会使用不同的参数计数Thing,你可以使用一些流量控制来适当地分配参数:

class Thing:
    def __init__(self, *args):
        if len(args) == 3:
            self.att3 = args[2]
        if len(args) > 2:
            self.att2 = args[1]
        if len(args) > 1:
            self.att1 = args[0]

有时kwargs更合适:

class Thing:
    def __init__(self, **kwargs):
        self.pitch = kwargs.get('pitch', DEFAULT_PITCH)
        self.yaw  = kwargs.get('yaw', DEFAULT_YAW)
        self.roll = kwargs.get('roll', DEFAULT_ROLL)
  

但是,如果我有30个属性

让我们希望这是夸张的,对吧?如果你接近那么多属性,那么现在可能是分解Thing的好时机。

答案 1 :(得分:1)

您可以使用*形式接受参数变量,例如

def __init__(self, *args):
    ...

然后,您可以创建像这样的新变量

def __init__(self, *args):
    for idx, item in enumerate(args):
        setattr(self, "attr{}".format(idx), item)

答案 2 :(得分:0)

namedtuple 1dataclass 2可能就是您想要的