Как написать конструктор класса, принимающий как список значений, так и каждое значение отдельно - PullRequest
0 голосов
/ 22 января 2020

Если у меня есть список 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'

Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Компилятор не будет пытаться выяснить, что один аргумент должен быть распакован; Вы можете либо поместить этот лог c в __init__ сам (не рекомендуется, так как это сложно, если вы хотите, чтобы итеративный аргумент использовался как есть, а не распакован), или определить метод класса как альтернативный метод создания 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 голос
/ 22 января 2020

Вы можете проверить в пределах __init__, хотя это не рекомендуется, как упомянуто в ответе Чепнера, поскольку это позволяет вводить более неоднозначные данные, поэтому вам нужно будет делать больше проверок. Но если это то, что вы хотите сделать, вот простая реализация:

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}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...