python基础(对象的进阶之三大属性)
一、对象继承:
1.1 继承:
特点:
提高代码的重用性,减少了代码的冗余
父类是object的类 —— 新式类,在Python3版本之后都是新式类
类总是要调用init方法,如果我们不写,实际上就调用父类object的__init__方法了
继承中使用属性时,如果自己有 就用自己的,如果自己没有 就用父类的,如果父类也没有 就报错
继承思想:
对象 -->类 -->基类
基类 -继承-> 子类 -实例化-> 对象
1.2 单继承:
特点:
可以有效的帮我们提高代码的重用性
在子类和父类有同名方法的时候,默认只执行子类的方法
如果想要执行父类的方法,可以在子类的方法中通过父类的类名调用父类的方法
单继承示例:

# 动物属性继承示例: class Animal(object): def __init__(self, name, kind): self.name = name self.kind = kind def eat(self, food): print('%s eat %s' % (self.name, food)) 猫的属性继承: class Cat(Animal): # 派生属性 def __init__(self, name, kind, eyes_color): self.eyes_color = eyes_color # super(Cat,self).__init__(name,kind) # 前面的类名和self可以忽略不写(方式一) # super().__init__(name,kind) # self参数默认传参,不需要指定(方式二) Animal.__init__(self, name, kind) # 通过父类类名传参(方式三) def climb(self): # 派生方法 print('%s climb tree'%self.name) 狗的属性继承: class Dog(Animal):pass hua = Cat('小花', '橘猫', '蓝色') print(hua.__dict__) # 打印对象的属性字典
1.3 多重继承:
特点:
规范复杂的功能与功能之间的关系
在多继承中,super方法就只和mro顺序有关系,和父类子类没有关系
多重继承示例:

# 多继承示例: # 各种动物,每一种动物都是一个类 # 青蛙、天鹅、老虎、鹦鹉 # 青蛙 :走,游泳 # 天鹅 :走,游泳,飞 # 老虎 :走,游泳 # 鹦鹉 :走,飞,说话 # 定义飞禽类 class FlyAnimal: def fly(self):pass # 定义水生类 class SwimAnimal: def swim(self):pass def eat():pass # 定义的走兽类 class WalkAnimal: def walk(self):pass def eat():pass # 青蛙继承的类 class Frog(SwimAnimal,WalkAnimal): pass # 老虎继承的类 class Tiger(SwimAnimal,WalkAnimal):pass # 天鹅继承的类 class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass # 鹦鹉继承的类 class Parrot(FlyAnimal,WalkAnimal): def talk(self): pass
继承时如果出现多个和父类都有,那么用谁的?
1.4 多继承之钻石继承问题:
图例: 广度优先
钻石继承示例:

# 钻石继承示例: # 遵循原则: 广度优先(C3算法) class A(object): def func(self): print('a') class B(A): pass # def func(self): # print('b') class C(A): pass # def func(self): # print('c') class D(B,C): pass # def func(self): # print('d') d = D() d.func() # d --> b --> c --> a
1.5 多重继承之乌龟继承问题:
图例:
乌龟继承示例:

# C3算法是怎么计算的: class A(object): def func(self): print('a') class B(A): pass # def func(self): # print('b') class C(A): pass # def func(self): # print('c') class D(B): pass # def func(self): # print('d') class E(C): pass # def func(self): # print('e') class F(D,E): pass # def func(self): # print('f') f = F() f.func() print(F.mro()) # 就是帮助我们来展示c3算法的继承顺序 FDBECAO
乌龟继承之C3算法剖析:

C3算法剖析: 元素提取提取规则: 每次获取一个类 如果从左到右第一个类, 在后面的继承顺序中也是第一个,或者不再出现在后面的继承顺序中 那么就可以把这个点提取出来,作为继承顺序中的第一个类 A= [AO] B = B ,[AO] B这个节点的继承顺序 :[BAO] C = C ,[AO] C这个节点的继承顺序 :[CAO] D = D ,[BAO] D这个节点的继承顺序 :[DBAO] E = E ,[CAO] E这个节点的继承顺序 :[ECAO] F = E ,[DBAO],[ECAO] F这个节点的继承顺序 :[DBAO],[ECAO] 定义L列表: 这里根据规则进行筛选排序: L[F] = F,[DBAO],[ECAO] [F] = [DBAO],[ECAO] [FD] = [BAO],[ECAO] [FDB] = [AO],[ECAO] [FDB] = [AO],[ECAO] [FDBE] = [AO],[CAO] [FDBEC] = [AO],[AO] [FDBECA] = [O],[O] [FDBECAO] # 最终的继承顺序
二、 对象的多态:
2.1 type 与 class 关系:
概念:
对象是被创造出来 被类实例化出来的
类也是被创造出来的 特殊的方式来创造类
分类:
常规创造的类: 总是有几个特性
能够实例化
能有属性
能有方法
元类 :能够帮助你创造不同寻常的类
特殊的需求一 : 不能实例化
特殊的需求二 : 只能有一个实例
图例:
示例:

# 一切皆对象: class A:pass # 自己创建类 print(type(A)) # 自建类 print(type(int)) # 内置类 print(type(str))
总结:
类 = type(对象)
type = type(类)
2.2 归一化设计:
2.2.1 抽象类:
特点:
单继承的规范
约束所有的子类 必须实现被abstractmethod装饰的方法名
给我们的代码制定规范(规则)
抽象类不能实例化,只是作为具体的类的规范
抽象类里面定义的所有的抽象方法 内部是可以完成一些简单的代码
示例:

# 抽象类设计示例: from abc import ABCMeta, abstractmethod # 规范: # 之所以写一个pay是为了提醒所有子类你一定要实现一个pay方法 class Payment(metaclass=ABCMeta): # 抽象类 # 付钱 @abstractmethod # 如果我必须要实现pay方法,那么我需要给pay加一个装饰器 def pay(self): pass # 创建的这个pay并没有内容, # 退款 @abstractmethod def back(self): pass # 程序设计: # 微信支付: class Wechatpay(Payment): def __init__(self,name,money): self.name = name self.money = money def pay(self): print('%s通过微信支付了%s元'%(self.name,self.money)) # 支付宝支付: class Alipay(Payment): def __init__(self,name,money): self.name = name self.money = money def pay(self): print('%s通过支付宝支付了%s元'%(self.name,self.money)) # apple支付: class ApplePay(Payment): def __init__(self, name, money): self.name = name self.money = money def pay(self): print('%s通过apple pay支付了%s元' % (self.name, self.money)) def back(self): print('退款') # 归一化设计接口: def pay(person): person.pay() # 实例化一个对象 ApplePay('alex',20000)
2.2.2 接口类:
特点:
多继承的规范
接口类里面定义的所有的接口方法 内部是可以完成一些简单的代码

# 接口类示例: from abc import ABCMeta,abstractmethod # 接口规范: # 动物都有的特性: class NormalAnnimal(metaclass=ABCMeta): # 吃 @abstractmethod def eat(self):pass # 喝 @abstractmethod def drink(self):pass # 程序设计: # 飞禽类: class FlyAnimal(metaclass=ABCMeta): @abstractmethod def fly(self):pass # 水生类: class SwimAnimal(metaclass=ABCMeta): @abstractmethod def swim(self):pass # 陆生类 class WalkAnimal(metaclass=ABCMeta): @abstractmethod def walk(self):pass # 接口类实现多继承: class Frog(NormalAnnimal,SwimAnimal,WalkAnimal):pass class Tiger(NormalAnnimal,SwimAnimal,WalkAnimal):pass class Swan(NormalAnnimal,FlyAnimal,SwimAnimal,WalkAnimal):pass class Parrot(NormalAnnimal,FlyAnimal,WalkAnimal): # 特殊方法: def talk(self): pass
2.3 多态:
定义:
广义:多态指的是一类事物有多种形态,动物可以表现成猪\狗\羊
狭义 : 在函数接收参数的时候,接收的多个类的对象同属于一个父类
特点:
对扩展开放(Open for extension):允许子类重写方法函数
对修改封闭(Closed for modification):不重写,直接继承父类方法函数
示例一:

class Person(object): def __init__(self,name,sex): self.name = name self.sex = sex def print_title(self): if self.sex == "male": print("man") elif self.sex == "female": print("woman") class Child(Person): # Child 继承 Person def print_title(self): if self.sex == "male": print("boy") elif self.sex == "female": print("girl") May = Child("May","female") Peter = Person("Peter","male") print(May.name,May.sex) print(Peter.name,Peter.sex) May.print_title() Peter.print_title()
示例二:

import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.abstractmethod def talk(self): pass class People(Animal): #动物的形态之一:人 def talk(self): print('say hello') class Dog(Animal): #动物的形态之二:狗 def talk(self): print('say wangwang') class Pig(Animal): #动物的形态之三:猪 def talk(self): print('say aoao')
2.4 鸭子类型:
描述:
我们只是通过一种潜规则的约定,如果具有__iter__,__next__就是迭代器
如果具有__hash__方法就是可哈希
如果具有__len__就是可以计算长度的
定义:
数据类型之间的关系并不仅仅是通过继承来约束的
是通过约定俗成的关系来确认的
示例:

#二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用 class TxtFile: def read(self): pass def write(self): pass class DiskFile: def read(self): pass def write(self): pass
三、封装:
3.1 私有化:
定义:
广义上的封装 : 把方法和属性根据根据类别装到类中
狭义上的封装 : 私有化的方法和属性
格式:
把一个属性加上双下划线 __属性名
类似:__price
特点:
类的外部不能私有化(_类名__属性)变量,类的私有化是在类的内部完成,外部是不能访问或者查看的
方法\静态变量\实例变量(对象属性)都可以私有化
实例变量(对象属性),静态变量(类变量),方法都不能被子类继承
私有化的两种形态(属性 + 方法):

# 私有化对象属性和类属性: class Goods: __weight = 5 # 静态变量的私有化 def __init__(self, name, price): self.name = name self.__price = price # 私有对象属性 def get_price(self): print(self.__price) apple = Goods('苹果', 5) print(apple.name) print(apple._Goods__price) # 私有对象属性的强制性获取,不建议使用 print(apple.__dict__) # 私有的方法: import hashlib class Auth: def __init__(self, user, pwd): self.username = user self.password = pwd # 私有化的方法,外部不能访问 def __md5_code(self): md5 = hashlib.md5(self.username.encode('utf-8')) md5.update(self.password.encode('utf-8')) return md5.hexdigest() def login(self): if self.username == 'alex' and 'ee838c58e5bb3c9e687065edd0ec454f' == self.__md5_code(): return True user = input('>>>') # 获取名字 pwd = input('>>>') # 获取密码 obj = Auth(user, pwd) ret = obj.login() if ret: print('登陆成功')
3.2 property 属性:
格式:
@属性
def 方法名(self):
语句体
property示例:

# 示例: # 计算圆形的面积 + 周长: class Circle: def __init__(self, r): self.r = r @property # 把装饰的一个方法伪装成一个属性 def area(self): return 3.14 * self.r ** 2 @property def perimeter(self): return 2 * 3.14 * self.r c1 = Circle(5) print(c1.area) # 面积 print(c1.perimeter) # 周长
property 与 私有化:

# property属性 与 私有化: # 示例: class Goods: discount = 0.8 # 静态变量 def __init__(self, name, price): self.name = name self.__price = price # 私有化变量 @property def price(self): # return self.__price * Goods.discount # 内部类调用静态变量(不建议使用) return self.__price * self.discount # 通过对象调用静态变量 # 苹果实例 apple = Goods('苹果', 5) print(apple.name) print(apple.price) # 香蕉实例 banana = Goods('香蕉', 10) print(banana.name) print(banana.price)
3.3 property 与 setter 方法:
格式:
@属性.setter
def 方法名(self,value):
条件:
修改属性
特点:
必须被property伪装
必须为property伪装的方法名同名

# 示例: class Goods: discount = 0.8 def __init__(self, name, price): self.name = name self.__price = price # 被property装饰的price方法 @property def price(self): p = self.__price * self.discount return p # 被setter装饰的price方法 @price.setter def price(self, value): self.__price = value apple = Goods('苹果', 5) banana = Goods('香蕉', 10) apple.price = 8 # 对应的调用的是被setter装饰的price方法 print(apple.price) # 对应调用的是被property装饰的price方法
3.4 property 与 deleter 方法:
特点:
类的方法,不支持修改,也不支持删除
类的属性与对象的属性可以被删除
格式:
@属性.deleter
def 方法名(self):
del 删除属性

# 示例: class Goods: discount = 0.8 def __init__(self, name, price): self.name = name self.__price = price # 私有化变量 @property def price(self): return self.__price * self.discount @price.deleter def price(self): del self.__price print('执行我啦') apple = Goods('苹果', 5) print(apple.name) print(apple.price) # 删除 私有化的对象属性(__price) del apple.price print(apple.__dict__) # 查看类属性字典
3.5 类方法(classmethod):
特点:
类方法需要至少一个默认参数 cls
类方法修改的是类中的静态变量/类变量
类方法不会和self有任何的操作关联
类方法接收的是当前我们所在的类的所有操作
类方法推荐使用类名调用而不是使用对象名调用
示例:

# 示例一: class Fruits: __discount = 0.8 def __init__(self, name, price): print('init', self) self.name = name self.__price = price # 把一个方法从对象方法,变成一个类方法 @classmethod def change_discount(cls, value): # cls 是:Fruits cls.__discount = value # 类方法表现形式一 @classmethod def get_discount(cls): print(cls.__name__) # 查看cls 类名 return cls.__discount print(Fruits.get_discount()) # 类名调用 Fruits.change_discount(1) print(Fruits.get_discount()) # 示例二: class Test(object): def abc(cls): print(cls.__name__) # 打印类名 # 类方法表现形式二 abc = classmethod(abc) # 通过普通的函数传参的方式创建类方法 a = Test() Test.abc() # 类能调用 a.abc() # 实例也能调用,不建议通过实例调用
3. 6 静态方法(staticmethod):
特点:
静态方法不需要默认参数
静态方法其实就是类中的一个普通函数,它并没有默认传递的参数
虽然静态方法没有默认参数, 但可以有参数
示例:

# 示例一: class A: @staticmethod def func(): # 此时 func是一个静态方法 print('既不操作和self相关的内容') print('也不操作和类名相关的内容') A.func() # 示例二: class Test(object): def abc(): print('abc') # 静态方法表现形式一 abc = staticmethod(abc) # 静态方法的表现形式二 @staticmethod def xyz(a, b): print(a + b) Test.abc() # 类调用 Test.xyz(1, 2) # 类调用 a = Test() a.abc() # 实例调用 a.xyz(3, 4) # 实例调用