Why can't I have a varargs constructor and another constructor with fixed arguments?
以下是迄今为止我所拥有的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class Die (object): def __init__(self,sides): self.sides = sides def roll(self): return random.randint(1,self.sides) def __add__(self,other): return Dice(self,other) def __unicode__(self): return"1d%d" % (self.sides) def __str__(self): return unicode(self).encode('utf-8') class Dice (object): def __init__(self, num_dice, sides): self.die_list = [Die(sides)]*num_dice def __init__(self, *dice): self.die_list = dice def roll(self): return reduce(lambda x, y: x.roll() + y.roll(), self.die_list) |
但当我尝试做
正如您在问题中观察到的,正在调用varargs构造函数。这是因为
Python不支持方法重载,因此您至少有两个选择。
- 仅定义varargs构造函数。检查参数列表的长度和前几个元素的类型,以确定要运行的逻辑。实际上,您可以将两个构造函数合并为一个。
- 将其中一个构造函数转换为静态工厂方法。例如,您可以删除第一个构造函数,保留varargs一个,然后定义一个新的工厂方法。
我更喜欢第二种方法,它允许您清晰地分离逻辑。您也可以为工厂方法选择更具描述性的名称;
1 2 3 | @staticmethod def from_n_sided_dice(num_dice, sides): return Dice([Die(sides)] * num_dice) |
旁注:这真的是你想要的吗?
编辑:您可以使用函数修饰符模拟方法重载(通过动态调度,而不是使用静态调度,但是静态类型在Python中不存在)。您可能需要设计自己的解决方案来支持
您想要的是一个单一的
1 2 3 4 5 6 7 8 | class Dice (object): def __init__(self, *args): if not isinstance(args[0], Die): self.die_list = [Die(args[0]) for _ in range(args[1])] else: self.die_list = args def roll(self): return sum(x.roll() for x in self.die_list) |