在__init__方法中检查输入类型是否合适?
我有一个类,想要根据几种不同的输入来初始化它。不过因为我不能使用函数重载,而且我对这门语言还不太熟悉,所以我不知道该怎么做。有没有什么建议?
4 个回答
2
与其他人的回答相反,在__init__
中检查类型并不罕见。例如,Python标准库中的array.array
类接受一个可选的initializer
参数,这个参数可以是列表、字符串或可迭代对象。文档明确说明,不同的类型会有不同的处理方式。另一个类似的例子是decimal.Decimal
。再比如zipfile.Zipfile
,它接受一个file
参数,“这个文件可以是文件的路径(字符串)或一个类似文件的对象。”(在这里,我们看到同时有明确的类型检查(字符串)和鸭子类型(类似文件的对象)!)
如果你发现__init__
中的类型检查变得很麻烦,可以尝试另一种方法。使用工厂函数来代替。例如,假设你有一个triangle
模块,里面有一个Triangle
类。构造一个三角形有很多种方法。与其让__init__
处理所有这些方式,不如在你的模块中添加工厂方法:
triangle.from_sas(side1, angle, side2)
triangle.from_asa(angle1, side, angle2)
triangle.from_sss(side1, side2, side3)
triangle.from_aas(angle1, angle2, side)
这些工厂方法也可以放到Triangle
类中,使用@classmethod
装饰器。想要了解这个技巧的一个很好的例子,可以看看Thomas Wouter在stackoverflow上关于重载init的回答。
3
在Python中,你应该使用鸭子类型。维基百科上有一段关于它在Python中使用的不错介绍,地址是 http://en.wikipedia.org/wiki/Duck_typing#In_Python