动态类型

数据的类型在运行时才确定。

  1. var = 123
  2. var = "abcd"

如果是静态类型语言(如 Java),编译时确定变量类型(编译后类型不能更改),那么你说 var 编译后是什么类型才好?
如果编译后是 string 型,那么运行时,运行到 var = 123 就会出错;
如果编译后是 int 型,那么运行时,运行到 var = “abcd” 就会出错。
所以说,Java 这种静态语言根本就不能这样写。

动态语言(如 Python)就不一样了,运行时才确定变量类型。
当运行到 var = 123 时,确定类型是 int 型;当运行到 var = “abcd” 时,确定类型是 str 型。

鸭子类型

多次调用函数,对于函数中某个参数,可以是不同的类型,只要这个参数所调用的方法都实现了即可;
而在静态语言中,需要实现共同的接口或有继承关系。

  1. class Parrot:
  2. def fly(self):
  3. print("Parrot flying")
  4. class Airplane:
  5. def fly(self):
  6. print("Airplane flying")
  7. class Whale:
  8. def swim(self):
  9. print("Whale swimming")
  10. def lift_off(entity):
  11. entity.fly()
  12. parrot = Parrot()
  13. airplane = Airplane()
  14. whale = Whale()
  15. lift_off(parrot) # Parrot flying
  16. lift_off(airplane) # Airplane flying
  17. lift_off(whale) # 'Whale' object has no attribute 'fly'

多次调用 lift_off,传进的参数是不同类型,但是 parrot、airplane 实现了 fly 方法,所以不会报错。

动态一时爽,重构火葬场。

鸭子类型所带来的问题:

  • 看代码的人根本就不知道 lift_off 要传入什么类型的参数。

  • fly 方法名就固定死了,无法重构,除非全部更改。

参考文档:
https://en.wikipedia.org/wiki/Duck_typing