[转]编程语言中的 鸭子模型(duck typing)
在学习Python的时候发现了鸭子类型这个术语,听起来好像很有意思一样,所以把它记下来。
鸭子类型的核心概念在于一个对象的有效语义,不是继承自特定的类或者实现特定的方法,而是
由当前的属性和方法集合决定的。听起来依旧很迷茫,简单的说:
"当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。"
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。
实际的例子1,将前两个参数相加后和第三个参数相乘:
1 def add_then_multiplication(a, b, c): 2 return (a + b) * c 3 4 print add_then_multiplication(1, 2, 3) 5 print add_then_multiplication([1, 2, 3], [4, 5, 6], 2) 6 print add_then_multiplication('hello', 'world', 9)
只要参数之间支持+和*运算,就在不使用继承的情况下实现多态。
例子2,鸭子和人:
1 class Duck: 2 def quack(self): 3 print "Quaaaaack..." 4 def feathers(self): 5 print "The Duck has feathers." 6 7 class Person: 8 def quack(self): 9 print "Person is not a duck" 10 def feathers(self): 11 print "The person takes a feather from the ground and shows it." 12 13 def in_the_forest(duck): 14 duck.quack() 15 duck.feathers() 16 17 def game(): 18 donald = Duck() 19 john = Person() 20 in_the_forest(donald) 21 in_the_forest(john) 22 23 game()
这个例子中,可以看出来,人不是鸭子,但是一旦拥有的鸭子的一些方法,就可以被当成--鸭子类型。
"在Python中,鸭子类型的最典型例子就是类似file的类。这些类可以实现file
的一些或全部方法,并可以用于file
通常使用的地方。" 但是一旦一个类不具有鸭子的方法,大概是要出错的。如:
1 class Duck: 2 def quack(self): 3 print "Quaaaaack..." 4 def feathers(self): 5 print "The Duck has feathers." 6 7 class Person: 8 def quack(self): 9 print "Person is not a duck" 10 def feathers(self): 11 print "The person takes a feather from the ground and shows it." 12 13 class Car: 14 def run(self): 15 print "Car is running" 16 17 def in_the_forest(duck): 18 duck.quack() 19 duck.feathers() 20 21 def game(): 22 donald = Duck() 23 john = Person() 24 in_the_forest(donald) 25 in_the_forest(john) 26 car = Car() 27 try: # will throw exception 28 in_the_forest(car) 29 except (AttributeError, TypeError): 30 print "No the method for duck typing" 31 32 game() 33
"在更实际的实现类似file的行为的例子中,人们更倾向于使用Python的异常处理机制来处理各种各样的可能因为各种程序员无法控制的环境和operating system问题而发生的I/O错误。在这里,“鸭子类型”产生的异常可以在它们自己的子句中捕获,与操作系统、I/O和其他可能的错误分别处理,从而避开复杂的检测和错误检查逻辑。"
个人认为:鸭子类型也许能够避免一些类的重写,无需大量复制相同的代码,但是需要良好的文档支持,不然会让代码变得很混乱,谁知道你的鸭子是不是我的鹅呢?哈哈
来自维基百科: 鸭子类型