03-深入类和对象
一、深入类和对象
1.1、鸭子类型和多态
维基百科中的解释为:
鸭子类型(英语:duck typing)在程序设计中是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。这个概念的名字来源于由詹姆斯·惠特科姆·莱利提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型。
class Cat(): def say(self): print("I am a cat") class Dog(): def say(self): print("I am a dog") class Duck(): def say(self): print("I am a duck") animal_list = [Cat,Dog,Duck] for animal in animal_list: animal().say()#实例化对象,在调用say方法 三个类实现同一个方法名,这就是多态。然后可以将这些类归为一种类型(鸭子类型) #python中的魔法函数充分也利用了鸭子类型的特性,可以在任一类中定义name_list = ["list1","list2"] name_list1 = ["love","python"] name_tuple = (3,4) name_set = set() name_set.add(5) name_set.add(6) name_list.extend(name_set) #参数name_set:['list1', 'list2', 5, 6]参数name_tuple:['list1', 'list2', 3, 4] print(name_list) # 参数:name_list1:['list1', 'list2', 'love', 'python']""" 这里说的是只要传入的参数是一个可迭代的类型就可以, 就连我们自定义的类将类的魔法函数__getitem__(返回 )、__iter__就可以变成可迭代的,都可以传入 def extend(self, *args, **kwargs): # real signature unknown Extend list by appending elements from the iterable. pass """#首先这三个类里面都包含了这个say()方法,如果在JAVA里边,要实现多态的话,需要继承父类在覆盖父类的方法实现多态。 # 例如:一般情况先定义一个父类Animal,然后这个Animal有一个say()方法。 # 然后在写其他类例如上面的Cat类,Cat类继承Animal类,然后重写say()方法。 # 然后指定类型实例化这个Cat对象,在python中不需要指定类型,在JAVA中(静态语言)必须指定类型, #这是动态语言和静态语言最大的区别。在python中都要做的一件事就是每个对象下都要写这个say()方法
1.2、抽象基类(abc)
python里边的抽象基类,是不能够实例化的。python是动态语言,动态语言是没有变量的类型的。在python中变量只是一个符号而已,这个符号可以指向任何类型的对象。动态语言缺少编译时检查错误的环境,在python中编写代码是很难发现错误的,只有要运行解释器才能找到错误。这也是动态语言共有的一个缺陷。python信奉的是鸭子类型,鸭子类型贯穿于整个面向对象之中。抽象基类是什么意思?在这个基础的类当中,设定好一些方法,然后所有的继承这个基类的类,都必须覆盖这个抽象基类里面的方法。抽象基类是无法实例化的。
##################去检查某个类是否有某种方法#############################class Students(object): def __init__(self,student_list): self.student = student_list def __len__(self): return len(self.student) students = Students(["lishuntao","test",