多重继承
Python支持多重继承,一个子类可以有多个“直接父类”。 这样,就具备了“多个父类”的特点。但是由于,这样会被“类的整体层次”搞的异常复杂,尽量避免使用。
#多重继承
class A:
def aa(self):
print("aa")
class B:
def bb(self):
print("bb")
class C(B,A):#子类C有两个直接父类B和A
def cc(self):
print("cc")
c=C()
c.cc()
c.bb()
c.aa()#类A、B中的对象都可调用
MRO()方法
Python支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左到右”按顺序搜索。
MRO(Method Resolution Order):方法解析顺序。我们可以通过mro()方法获得“类的层次结构”,方法解析顺序也是按照这个“类的层次结构”寻找的。
#多重继承
class A:
def aa(self):
print("aa")
def say(self):
print("say AAA")
class B:
def bb(self):
print("bb")
def say(self):
print("say BBB")
class C(B,A):#顺序是先B后A
def cc(self):
print("cc")
c=C()
c.say()
结果是调用B的方法
super()获得父类定义
在子类中,如果想要获得父类的方法时,我们可以通过super()来做。
super()代表父类的定义(看成代码),不是父类对象。
#测试super(),代表父类的定义,而不是父类的对象
class A:
def say(self):
print("A:",self)
class B(A):
def say(self):
#A.say(self)
super().say()#获得父类的方法,与上面一句代码等价
print("B:",self)
B().say()
多态
多态是指同一个方法调用由于对象不同可能产生不同的行为。
注意:
1.多态是方法的多态,属性没有多态。
2.多态的存在有2个必要条件:继承、方法重写。
#测试多态
class Man:
def eat(self):
print("饿了,吃饭啦!")
class Chinese(Man):#继承
def eat(self):#方法重写
print("中国人用筷子吃饭")
class English(Man):
def eat(self):
print("英国人用叉子吃饭")
class Indian(Man):
def eat(self):
print("印度人用右手吃饭")
def manEat(m):
if isinstance(m,Man): #多态,一个方法调用,根据对象不同调用不同的方法
m.eat()
else:
print("不能吃饭")
manEat(Chinese())
manEat(Indian())
特殊方法和运算符重载
常见的特殊方法统计如下:
每个运算符都对应了相应的方法:
#测试运算符的重载
class Person:
def __init__(self,name):
self.name=name
def __add__(self, other):#加法重载
if isinstance(other,Person):#判断other是否与Person类的实例属性同一类型
return"{0}--{1}".format(self.name,other.name)
else:
return "不是同类对象,不能相加"
def __mul__(self,other):#乘法重载
if isinstance(other,int):
return self.name*other
else:
return "不是同类对象,不能相乘"
p1=Person("Meidi")
p2=Person("Zhang")
x=p1+p2
print(x)
print(p1*3)
特殊属性
直接上例子!
#测试特殊属性
class A:
pass
class B:
pass
class C(B,A):
def __init__(self,n):
self.n=n
def cc(self):
print("cc")
c=C(3)
print(dir(c)) #返回对象的方法、属性列表
print(c.__dict__) #对象的属性字典
print(c.__class__) #对象所属的类
print(C.__bases__) #类的(父)基类
print(C.__mro__) #类层次结构
print(A.__subclasses__()) #子类列表
对象的浅拷贝和深拷贝
变量的赋值操作
只是形成两个变量,实际还是指向同一个对象。
浅拷贝
Python拷贝一般都是浅拷贝。拷贝时,对象包含的子对象内容不拷贝。因此,源对象和拷贝对象会引用同一个子对象。
深拷贝
使用copy模块的 deepcopy 函数,递归拷贝对象中包含的子对象。源对象和拷贝对象所有的子对象也不同。
#测试对象的浅拷贝、深拷贝
import copy
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu=cpu
self.screen=screen
class CPU:
def calculate(self):
print("算数")
print("cpu对象:",self)
class Screen:
def show(self):
print("显示")
print("screen对象:",self)
#测试变量赋值
c1=CPU()
c2=c1
print(c1)
print(c2)
#测试浅复制
s1=Screen()
m1=MobilePhone(c1,s1)
m2=copy.copy(m1)
print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen)
#测试深复制
m3=copy.deepcopy(m1)
print(m1,m1.cpu,m1.screen)
print(m3,m3.cpu,m3.screen)
D:\Anaconda3\python.exe D:/PycharmProjects/untitled/obj.py
<__main__.CPU object at 0x00000216284D1D68>
<__main__.CPU object at 0x00000216284D1D68>#变量赋值,指向同一对象
<__main__.MobilePhone object at 0x00000216284EE160> <__main__.CPU object at 0x00000216284D1D68> <__main__.Screen object at 0x00000216284EE128>
<__main__.MobilePhone object at 0x00000216284EED30> <__main__.CPU object at 0x00000216284D1D68> <__main__.Screen object at 0x00000216284EE128>#浅拷贝,只拷贝其本身,还是引用同一子对象
<__main__.MobilePhone object at 0x00000216284EE160> <__main__.CPU object at 0x00000216284D1D68> <__main__.Screen object at 0x00000216284EE128>
<__main__.MobilePhone object at 0x00000216266EC9B0> <__main__.CPU object at 0x0000021629546860> <__main__.Screen object at 0x00000216295469B0>#深拷贝,整个家族都拷贝了,引用不同的子对象
Process finished with exit code 0
组合
继承:“is-a”关系,从而实现子类拥有的父类的方法和属性。
“is-a” 关系指的是类似这样的关系:狗是动物,dog is animal。狗类就应该继承动物类。
组合: “has-a”关系,也能实现一个类拥有另一个类的方法和属性。”
has-a”关系指的是这样的关系:手机拥有 CPU。 MobilePhone has a CPU。
#使用继承实现代码的复用
class A1:
def say_a1(self):
print("a1,a1,a1")
class B1(A1):#继承
pass
b1=B1()
b1.say_a1()
#使用组合实现代码的复用
class A2:
def say_a2(self):
print("a2,a2,a2")
class B2:
def __init__(self,a):
self.a=a
a2=A2()
b2=B2(a2)#组合,也可以与上一句合并写成b2=B2(A2())
b2.a.say_a2()
#组合has-a
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu=cpu
self.screen=screen
class CPU:
def calculate(self):
print("算数")
print("cpu对象:",self)
class Screen:
def show(self):
print("显示")
print("screen对象:",self)
m=MobilePhone(CPU(),Screen()) #组合
m.cpu.calculate()
m.screen.show()
设计模式_工厂模式实现
工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。
#测试工厂模式
class CarFactory:
def create_car(self,brand):#工厂模式特点
if brand=="奔驰":
return Benz()
elif brand=="宝马":
return BMW()
elif brand=="比亚迪":
return BYD()
else:
return "未知品牌,无法创建"
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory=CarFactory()
c1=factory.create_car("奔驰")
c2=factory.create_car("比亚迪")
print(c1)
print(c2)
设计模式_单例模式实现
单例模式(Singleton Pattern)的核心作用是确保一个类只有一个实例,并且提供一 个访问该实例的全局访问点。
单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较 多的资源,如读取配置文件、产生其他依赖对象时,可以产生一个“单例对象”,然后永久 驻留内存中,从而极大的降低开销。
单例模式有很多方法,这里推荐用重写new方法、构造器方法。
# 一种单例固定模式的测试
class MySingleton:
__obj = None #定义一个类属性,做判断,对象保存在这里
__init_flag = True
def __new__(cls, *args, **kwargs):
if cls.__obj == None:
cls.__obj = object.__new__(cls)#通过父类的__new__(cls)创建实例
return cls.__obj #创建单例对象,并把建好的对象放到类属性上去,以后可以通过MySingleton.object访问
def __init__(self,name):
if MySingleton.__init_flag:
print("init....")
self.name = name
MySingleton.__init_flag = False#T变F,再也不重构建
a = MySingleton("aa")
print(a)
b = MySingleton("bb")
print(b)
应用到工厂模式中:
# 单例模式
class CarFactory:
__obj = None
__init_flag = True
def create_car(self, brand):
if brand == "奔驰":
return Benz()
elif brand == "宝马":
return BMW()
elif brand == "比亚迪":
return BYD()
else:
return "未知品牌,无法创建"
def __new__(cls, *args, **kwargs):
if cls.__obj == None:
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self):
if CarFactory.__init_flag:
print("init CarFactory...")
CarFactory.__init_flag = False
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory= CarFactory()
c1 = factory.create_car("奔驰")
c2 = factory.create_car("比亚迪")
print(c1)
print(c2)
factory2 = CarFactory()
print(factory)
print(factory2)
注意:
1)__new__方法是静态类方法,虽然没有加静态类方法的装饰器;
2)A继承object类,虽然通常可以省略object字样。但这里省略就无法执行__new__方法。若A继承其他类,同样可以使用object的__new__方法,也可以使用父类的__new__方法;
3)在实例化对象的时候,__new__方法在__init__方法之前执行;
4)__new__必须返回一个对象,才能给__init__初始化。
在网上搜索了单例模式相关博客,注意内容转载自CNblog博主「zaituzhong」的原创文章https://www.cnblogs.com/tingxin/p/12197904.html