假设我有一个列表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'
我该怎么办?
编译器不会尝试找出应该解压缩单个参数的位置;您可以选择将此逻辑放在__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)
您可以在__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}