Python 具有多个参数的对象初始化

Python 具有多个参数的对象初始化,python,Python,有更好的方法吗 class MyClass: def __init__(self, my_var_1, my_var_2, my_var_3, my_var_4, my_var_5, my_var_6, my_var_7, my_var_8, my_var_9): self.my_var_1 = my_var_1 self.my_var_2 = my_var_2 self.my_var_3 = my_var_3 self.m

有更好的方法吗

class MyClass:
    def __init__(self, my_var_1, my_var_2, my_var_3, my_var_4, my_var_5, my_var_6, my_var_7, my_var_8, my_var_9):
        self.my_var_1 = my_var_1
        self.my_var_2 = my_var_2
        self.my_var_3 = my_var_3
        self.my_var_4 = my_var_4
        self.my_var_5 = my_var_5
        self.my_var_6 = my_var_6
        self.my_var_7 = my_var_7
        self.my_var_8 = my_var_8
        self.my_var_9 = my_var_9

假设变量名不遵循任何模式。

如果类的目的只是保存相关数据的集合(“普通旧数据类”),我会使用a(不可变)或a(可变):

其中
类型是每个字段的类型。不幸的是,在这种情况下,Python语法需要类型提示。无论如何,这是一个很好的实践,因为它们有助于减少在代码运行之前可能捕获的错误。如果确实不需要类型,可以使用较旧的
namedtuple
语法:

from collections import namedtuple

MyClass = namedtuple("MyClass", ["my_var_1", "my_var_2", "my_var_3"])
obj = MyClass(1, 2, 3)
print(obj)
# Prints MyClass(my_var_1=1, my_var_2=2, my_var_3=3)
所有这些选项都将为您生成该初始值设定项,以及其他功能,如nice
\uuuu str\uuuu
/
\uuuu repr\uu
方法。例如:

class MyClass(NamedTuple):
    my_var_1: int
    my_var_2: int
    my_var_3: int
    my_var_4: int
    my_var_5: int
    my_var_6: int
    my_var_7: int
    my_var_8: int
    my_var_9: int

obj = MyClass(1, 2, 3, 4, 5, 6, 7, 8, 9)
print(obj)
# Prints MyClass(my_var_1=1, my_var_2=2, my_var_3=3, my_var_4=4, my_var_5=5, my_var_6=6, my_var_7=7, my_var_8=8, my_var_9=9)
不需要手动初始值设定项定义


这两种类型之间的主要区别是,
dataclass
es可以修改,而
NamedTuple
s不能(与普通元组非常相似):

#上面的obj
打印(对象my_var_6)#打印6
obj.my_var_6=5
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:无法设置属性

如果希望能够像存储任意键/值对的对象的属性一样存储任意键/值对,而不必显式定义它们,则可以定义一个类,该类的行为类似于
dict
,但允许通过属性引用访问其键/值,如下所示:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

class MyClass(AttrDict):

    def __init__(self, *args, **kwargs):
        super(MyClass, self).__init__(*args, **kwargs)

        # Attributes built into your class
        self.predef = 'predefind'

    pass

# Define attributes at class creation time
mc = MyClass((('abc', '123'), ('foo', 'bar')))
print(mc.abc)
print(mc.foo)

# See that the class defined attribute is there
print(mc.predef)

# Change the value of an existing attribute
mc.abc = 'blah'
print(mc.abc)

# Create a new attribute
mc.xxx = 1111
print(mc.xxx)

from typing import NamedTuple

class MyClass(NamedTuple):
    my_var_1: int
    my_var_2: str
结果:

123
bar
predefined
blah
1111

如果您想要强制执行一组特定的参数/属性,那么您需要比这更复杂的东西,或者您想要使用其他替代方法之一。但是,如果您希望能够在对象上使用任意属性,并使用最少的设置编码(无),这就是您的答案。

“假设变量名称不遵循任何模式。”-在名称中不放置明显的大模式是有意义的,然后,另一个选项是接收带有**kwargs的关键字args,并通过dict循环以设置实例属性。您应该强制使用关键字args,因为您需要关键字来设置属性名称。“其他”实际上应该读为“其他”。在Python中,几乎总是有一些其他的高级方法来完成某些事情。您可以接收dict并更新self。作为一个非常简单的示例,使用它,而不是迭代它来设置属性。我认为这是Python为数不多的小麻烦之一,可能数据类试图解决这个问题。请注意,数据类仍然是普通类,它们不限于保存数据字段。我建议您展示一个初始化这些类的示例,因为这是问题的焦点。生成的初始值设定项看起来像什么?就你现在的回答而言,我没有证明这两种方法都是初始化对象的更好方法,这就是问题所问的——类型不是原始问题的一部分,所以你的回答在我看来有点“苹果vs橘子”。@Steve是的。不幸的是,当我下公共汽车时,我在应用程序中手机的Swype键盘上写下了这个答案。当我能使用一台合适的计算机时,我会尽力改进它。@Carcigenicate,回答SO问题时请不要冒险(我想我从来没有在SO上说过这样的话)。答案实际上是准确的,切中要害的,但它并没有解释原因,对于不知道的人来说,可能像Steve说的那样,因为类型注释。
# obj from above
print(obj.my_var_6)  # Prints 6

obj.my_var_6 = 5

Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: can't set attribute
class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

class MyClass(AttrDict):

    def __init__(self, *args, **kwargs):
        super(MyClass, self).__init__(*args, **kwargs)

        # Attributes built into your class
        self.predef = 'predefind'

    pass

# Define attributes at class creation time
mc = MyClass((('abc', '123'), ('foo', 'bar')))
print(mc.abc)
print(mc.foo)

# See that the class defined attribute is there
print(mc.predef)

# Change the value of an existing attribute
mc.abc = 'blah'
print(mc.abc)

# Create a new attribute
mc.xxx = 1111
print(mc.xxx)

from typing import NamedTuple

class MyClass(NamedTuple):
    my_var_1: int
    my_var_2: str
123
bar
predefined
blah
1111