如何编写一个同时接受值列表和每个值的类构造函数

问题描述 投票:-1回答:2

假设我有一个列表lst = [1 2 3](例如),我想编写一个名为Vector的类。当我将此列表传递给Vector时,即当我实例化Vector(lst)时,则它应提供与我要传递此列表相同的对象,如下所示:Vector(*lst)。更确切地说,当我想拥有时,我该如何写构造函数

Vector(lst) == Vector(*lst)

它应该是3维Vector。我尝试过

def __init__(self,x,y,z): # constructor
            self.x = x
            self.y = y
            self.z = z  

但是这会导致错误:

Traceback (most recent call last):
  File "main.py", line 12, in <module>
    test.assert_equals(Vector(examples[0]), Vector(*examples[0]))
TypeError: __init__() missing 2 required positional arguments: 'y' and 'z'

我该怎么办?

python class oop constructor
2个回答
2
投票

编译器不会尝试找出应该解压缩单个参数的位置;您可以选择将此逻辑放在__init__本身中(不建议使用,因为如果您希望按原样使用可迭代参数并解压缩not会很棘手),或者定义一个类方法作为替代方法创建Vector的方法。

class Vector:
    def __init__(self, x, y, z):
        ...

    @classmethod
    def from_list(self, lst):
        # Raises an IndexError if the list is too short,
        # and silently ignores values in lst[3:]
        return Vector(lst[0], lst[1], lst[2])

coords = [1, 2, 3]
v1 = Vector(*coords)
v2 = Vector.from_list(coords)

1
投票

您可以在__init__中进行检查,尽管不建议使用chepner的答案,因为这样可以提供更多含糊的输入,因此您需要进行更多检查。但是,如果您要这样做,这里是一个简单的实现:

class Vector:

    def __init__(self, *args):
        if len(args) == 1 and isinstance(args[0], list):
            args = args[0]
        self.x, self.y, self.z = args

lst = [1, 2, 3]

print(Vector(*lst).__dict__)
print(Vector(lst).__dict__)

输出:

{'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3}
© www.soinside.com 2019 - 2024. All rights reserved.