在 python 中,不能多次定义init函数,这在了解语言如何工作的情况下是相当公平的。当一个对象被创建时,init会被调用,因此,拥有两个对象会产生不确定性。然而,在某些设计中,这种特性是合乎需要的。例如:
class Triangle(object):
def __init__(self,vertices):
self.v1 = vertices[0]
self.v2 = vertices[1]
self.v3 = vertices[2]
def area(self):
# calculate the are using vertices
...
return result
class Triangle(object):
def __init__(self,sides):
self.v1 = sides[0]
self.v2 = sides[1]
self.v3 = sides[2]
def area(self):
# calculate the are using sides
...
return result
在这种情况下,我们要初始化相同数量的属性,并且它们是相关的,因此您可以从一个中获得另一个。确实,在这个特定示例中,可以使用顶点是元组而边可能是浮点数的事实(或字符串或其他东西)但当然并非总是如此。
一种可能的解决方案是将初始化过程委托给其他函数,例如:
class Triangle(object):
def __init__(self):
self.v1 = None
self.v2 = None
self.v3 = None
def byVertices(self,vertices):
self.v1 = vertices[0]
self.v2 = vertices[1]
self.v3 = vertices[2]
def sidesToVertices(self,sides):
# converts sides to vertices
...
return vertices
def bySides(self,sides):
vertices = sidesToVertices(sides)
self.v1 = vertices[0]
self.v2 = vertices[1]
self.v3 = vertices[2]
def area(self):
# calculate the are using vertices
...
return result
但它看起来不是很干净,并且像“区域”这样的所有功能都必须检查属性是否正确实例化(或采用 try/catch),这是很多代码,而且它破坏了项目的可读性. 总的来说,它看起来像是一个便宜的把戏。
另一种选择是告诉实例,你要初始化什么类型的属性:
class Triangle(object):
def __init__(self, data, type = "vertices"):
if type == "sides":
data = sideToVertices(self,sides)
else if type == "vertices":
pass
else:
raise(Exception)
self.v1 = data[0]
self.v2 = data[1]
self.v3 = data[3]
def sidesToVertices(self,sides):
# converts sides to vertices
...
return vertices
def area(self):
# calculate the are using vertices
这种其他方法似乎更可取,但是我不确定在init中引入逻辑有多少“pythonic” 。你对这件事有什么看法?有没有更好的方法来协调这种情况?