Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python3中实例化具有未知数量属性的类的实例_Python_Oop - Fatal编程技术网

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

在Python3中实例化具有未知数量属性的类的实例,python,oop,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

如何在不为所有属性指定默认值的情况下创建对象(可能有许多属性,比如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
。有办法摆脱这种状况吗?例如,假设稍后我添加了一个属性,我不想返回并将其添加到
\uuuu init\uuuu
函数中,或者我不想在创建对象实例时声明30个值-有办法吗

有办法吗

是的

例如:

class Thing:
    def __init__(self, *args):
        self.att1, self.att2, self.att3 = args
如果您有时使用不同的参数计数来制作
东西
s,您可以使用一些流控制来适当地分配参数:

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]
有时更合适:

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个属性


希望这是夸张吧?如果您接近这么多属性,那么现在可能是分解
东西的好时机

您可以接受带有
*
形式的参数变量,如下所示

def __init__(self, *args):
    ...
def __init__(self, *args):
    for idx, item in enumerate(args):
        setattr(self, "attr{}".format(idx), item)
然后,您可以创建这样的新变量

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

namedtuple
dataclass
可能就是您要寻找的

这绝对是夸张,我刚刚意识到为5个属性设置默认值会变得相当长。阅读有关参数解包的内容,听起来只有在我有一个列表或元组的情况下,这才有效,我说的是在实例化时不声明任何属性,然后再声明一个属性。因此,使用这种格式,我可以在对象实例化后添加任何属性,即使在调用
\uuuuu init\uuuu
时,也可以在对象实例化后添加任何属性,该对象已在内存中创建,并作为
self
传递。因此,您可以添加任何属性,如上面所示:-)@Startec您所说的用none实例化的
是什么意思,只要说
my_thing.name=
Test'`即使
name
属性从未在类声明中声明过?我喜欢这样,但您能帮我理解吗?即使使用
*args
实例化没有参数的对象(如我在上面的评论中所述),也会使该属性看起来不存在。因此,当我稍后去设置它时,我会预期
错误:东西没有属性“我试图设置的内容”