1.1.鸭子类型和多态
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。
实例一:
# 鸭子类型和多态简单实例 class Dog(object): def say(self): print('a dog') class Cat(object): def say(self): print('a cat') class Duck(object): def say(self): print('a duck') animal_list = [Dog,Cat,Duck] for animal in animal_list: animal().say() #运行结果 a dog a cat a duck
实例二:
类只要实现了__getitem__方法,它就是可迭代的,并不关心对象的本身,只关心行为,然后就可以当做extend的参数。
class Company(object): def __init__(self, employee_list): self.employee = employee_list def __getitem__(self, item): return self.employee[item] company = Company(["11", "22", "33"]) a = ['derek1','derek2'] name_set = set() name_set.add('tom1') name_set.add(('tom2')) #extend里面的参数介绍 #def extend(self, iterable): # real signature unknown; restored from __doc__ #""" L.extend(iterable) -> None -- extend list by appending elements from the iterable """ #extend里面可以添加任何可迭代的参数,给类添加一个魔法函数__getitem__,类就变成可迭代的,所以可以extend进去 a.extend(company) print(a) #['derek1', 'derek2', '11', '22', '33'] a.extend(name_set) print(a) #['derek1', 'derek2', '11', '22', '33', 'tom2', 'tom1']
1.2.抽象基类(abc模块)
抽象基类的作用类似于JAVA中的接口。在接口中定义各种方法,然后继承接口的各种类进行具体方法的实现。抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化
(1)判断类时候有某种属性
#判断类是否有某种属性 class Company(object): def __init__(self, employee_list): self.employee = employee_list def __len__(self): return len(self.employee) com = Company(["11", "22", "33"]) #hasattr判断类有没有某种属性,方法也是类的属性 print(hasattr(com,"__len__")) #True #虽然用hasattr可以判断,但正确的方式是定义一个抽象基类 #我们在某些情况下希望判定某个对象的类型,可以用抽象基类 from collections.abc import Sized print(isinstance(com,Sized)) #True # print(len(com))
class Sized(metaclass=ABCMeta): __slots__ = () @abstractmethod def __len__(self): return 0 @classmethod def __subclasshook__(cls, C): if cls is Sized: return _check_methods(C, "__len__") return NotImplemented