目录
一、类的构建与继承
二、多继承
三、钻石继承
四、多态
五、鸭子类型
六、类的组合
七、类的私有属性和方法
八、魔法方法
九、单例模式
一、类的构建与继承
类的属性包含成员变量和成员函数(方法)
成员函数又分为静态方法、魔法方法、普通成员方法
静态方法可以直接被类调用,也可以被类对象调用
魔法方法是类的默认方法,我们可以自定义魔法方法
子类继承父类,可以对相同函数名的函数进行重写
class Person: # Person(object)name = '没有名字'age = '未出生'sex = '不知道' # 静态属性@staticmethod # 静态方法def print_name():print(f'{Person.name}')# 实例属性方法(魔法方法)def __init__(self, name='无名氏', age=0, sex='未知'): # 初始化无返回值self.name = nameself.age = ageself.sex = sexdef printName(self):print(f'我的名字是: {self.name}')def printAge(self):print(f'我的年龄是: {self.age}')def printSex(self):print(f'我的性别是: {self.sex}')# 继承与Person的子类
class Son(Person):def printName(self): # 局部重写print(f'我有自己的名字, 叫做{self.name}:')def __init__(self, name='子女', age=1): # 局部继承Person.__init__(self)self.name = nameself.age = agePerson.print_name() # 类直接调用静态方法girl_friend = Person()
girl_friend.print_name() # 类对象调用静态方法
print(girl_friend.name)
girl_friend.printName()
girl_friend.printAge()
girl_friend.printSex()friend = Person('苏铭', 21, '男')
friend.print_name()
print(friend.name)
friend.printName()
friend.printAge()
friend.printSex()print(Son.name)
me = Son()
me.printName()
me.printAge()
me.printSex()
二、多继承
一个子类可以继承于多个父类,谁排前面谁优先继承,重名方法的继承需要考虑优先级,不重名方法的继承不需要考虑优先级(都继承)。
class Master:def __init__(self):self.kongfu = '传统奶茶配方'def make_cake(self):print(f'[传统] 按照{self.kongfu}制作了一杯奶茶...')def smoke(self):print('抽个烟')class School:def __init__(self):self.kongfu = '现代奶茶配方'def make_cake(self):print(f'[现代] 按照{self.kongfu}制作了一杯奶茶...')def drink(self):print('躲在厕所里喝酒')# 多继承
class Prentice(Master, School): # 谁排前面,谁优先继承pass# 子类的魔法属性__mro__决定了属性和方法的优先级
print(Prentice.__mro__)me = Prentice()
print(me.kongfu)
me.make_cake()
me.smoke()
me.drink() # 不重名的不考虑顺序问题
三、钻石继承
如果子类继承自两个单独的超类,而那两个超类又继承自同一个公共基类,那么就构成了钻石继承体系。这种继承体系很像竖立的菱形,也称作菱形继承。
super()方法保证公共父类只被执行一次
class A:def __init__(self):print('进入A')print('离开A')class B(A):def __init__(self):print('进入B')super().__init__()print('离开B')class C(A):def __init__(self):print('进入C')super().__init__()print('离开C')class D(B, C):def __init__(self):print('进入D')super().__init__()print('离开D')D()
四、多态
多态: 不同对象在调用相同方法时, 呈现不同状态
isinstance()方法可以判断一个对象是否属于某一个类
class Animal():def eat(self):print('动物吃饭了')class Dog(Animal):def eat(self):print('小狗吃饭了')class Cat(Animal):def eat(self):print('小猫吃饭了')a = Animal()
b = Dog()
c = Cat()print(isinstance(a, Animal)) # True 判断 a 是否输入 Animal类
print(isinstance(b, Dog)) # True
print(isinstance(c, Cat)) # True
print()
print(isinstance(b, Animal)) # True
print(isinstance(c, Animal)) # True 同一个对象可以属于不同的类
print()
print(isinstance(a, Dog)) # False 父类对象不属于子类
print()def eat_eat(animal):animal.eat()_list = [Animal, Dog, Cat]
for animal in _list:animal().eat()
五、鸭子类型
鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。
class Duck:def quack(self):print('嘎嘎嘎, 我是一只可达鸭')def feathers(self):print('我有黄色的羽毛')class Person:def quack(self):print('我也会嘎嘎嘎, 但我是一个人')def feathers(self):print('我没有羽毛')def in_the_poor(d):d.quack()d.feathers()duck = Duck()
person = Person()
in_the_poor(duck)
in_the_poor(person)
六、类的组合
类的组合就是一个对象具有一个属性,这个属性的指是另外一个类的对象。
# 乌龟类
class Turtle:def __init__(self, x):self.num = x# 鱼类
class Fish:def __init__(self, x):self.num = x# 池塘类
class Pool:def __init__(self, x, y):#乌龟类进来self.turtle = Turtle(x)#鱼类进来self.fish = Fish(y)def print_num(self):print(f'池塘里有{self.turtle.num}只乌龟, 有{self.fish.num}只鱼')p = Pool(4, 10)
p.print_num()
七、类的私有属性和方法
私有权限:在属性名和方法名 前面 加上两个下划线 __ 类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;
类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问; 私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。
class People(object):def __init__(self, password):self.__password = password # 变量前面有两个下划线, 有私有属性, 外部不可直接访问def getPassword(self):return self.__password # 类的内部可调用私有属性def setPassword(self, new_password):if len(new_password) >= 6:self.__password = new_passwordelse:print('密码长度需大于等于5')me = People('123456')
print(me.getPassword())
me.setPassword('654321')
print(me.getPassword())
八、魔法方法
Python中的魔法方法(Magic Methods),也称为双下划线方法(Dunder Methods),是特殊方法,其名称以双下划线开头和结尾,例如 __init__、__str__、__add__ 等。这些方法提供了一种使Python对象能够使用内置函数和语言结构的方式。
class Obj(int):def __init__(self, num):self.num = num# 自定义类对象的基本计算方法def __add__(self, other):return self.num + other + 1 # 这里的运算符继承于父类def __sub__(self, other):return self.num - other + 1def __mul__(self, other):return self.num * other + 1def __truediv__(self, other):return self.num / other + 1def __floordiv__(self, other):return self.num // other + 1# __str__ 是一个显示对象信息的魔法方法# 这个方法需要return一个数据, 并且只有self一个参数# 当在类的外部print(对象), 则打印这个返回的数据def __str__(self):return (f'这个数是{self.num}')# __getattr__(self)当访问一个不存在的对象时, 不报错# 是一个防报错的异常捕获机制def __getattr__(self, name):return (f'{name}属性不存在')a = Obj(3)
b = Obj(5)
print(a)
print(type(a))
print(a.x)
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a // b)class String(str):def __init__(self, name):self.name = name# __len__(self) 可自定义长度的计算方法def __len__(self):return len(self.name) - 1def __str__(self):return f'这个字符串是{self.name}'s = String('hello')
print(s)
print(len('hello'))
print(len(s))
九、单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
class Single:#创建类的隐藏属性__instance = None #父类new方法的返回值, None的bool值为Falsedef __new__(cls):#如果__instance的值为None, 就创建一个对象并赋值if not cls.__instance:cls.__instance = object.__new__(cls)return cls.__instancea = Single()
b = Single()
print(id(a), id(b)) # 地址一样a.name = '周周'
a.sex = '帅哥'
print(a.name, a.sex)
print(b.name, b.sex)b.name = '提速狗'
b.sex = '美女'
print(a.name, a.sex)
print(b.name, b.sex)