MRO(method resolution order)
Python 支持多继承,如果父类中有相同名字的方法,在子类中没有指定父类名字的时候,解释器将根据 从左到右 按顺序搜索。 我们可以通过 类.mro() 来获得类的层次结构图 ,方法 的解析顺序也是按照这个来的。
class A:
def aa(self):
print("aa")
def say(self):
print("aa")
class B:
def bb(self):
print("bb")
def say(self):
print("bb")
class C(B,A):
def cc(self):
print("cc")
c = C()
print(C.mro())
c.say()
[<class ‘main.C’>, <class ‘main.B’>, <class ‘main.A’>, <class ‘object’>]
bb
super()
class A:
def aa(self):
print("aa")
def say(self):
print("aa")
class B(A):
def bb(self):
print("bb")
def say(self):
super().say()
print("bb")
b = B()
b.say()
aa
bb
多态
class Animal:
def shout(self):
print("动物叫了")
class Cat(Animal):
def shout(self):
print("小猫叫了")
class Dog(Animal):
def shout(self):
print("小狗叫了")
def animalShout(a):
if isinstance(a,Animal):
a.shout()
animalShout(Dog())
animalShout(Cat())
小狗叫了
小猫叫了
特殊方法跟运算符重载
Python中的符号运算都是通过调用特殊方法来实现的比如
a = 20
b = 30
c = a + b
d = a.__add__(b)
print("c=",c)
print("d=",d)
50
50
重写若干方法 实现运算符的重载
class Person:
def __init__(self,name):
self.name = name
def __add__(self, other):
if isinstance(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("sowhat")
p2 = Person("student")
x = p1 + p2
print(x)
print(p1*3)
sowhat–student
sowhatsowhatsowhat
特殊属性
Python对象中 还包含很多双下划线开始跟结束的属性,如下:
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__())
[‘class’, ‘delattr’, ‘dict’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘le’, ‘lt’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘cc’, ‘n’]
{‘n’: 3}
<class ‘main.C’>
(<class ‘main.B’>, <class ‘main.A’>)
[<class ‘main.C’>, <class ‘main.B’>, <class ‘main.A’>, <class ‘object’>]
[<class ‘main.C’>]
对象的浅拷贝跟深拷贝
- 变量的赋值操作:只是形成了两个变量,实际上还是指向同一个对象。
- 浅拷贝:Python的拷贝一般都是浅拷贝,拷贝的时候 只将原对象复制一份,原对象里的子对象内容不拷贝,因此原对象跟拷贝对象会引用同一个子对象 copy.copy()
- 使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象跟拷贝对象中的所有子对象也是不同的。
#coding=utf-8
import time
import math
import copy
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu = cpu
self.screen = screen
class CPU:
def calculate(self):
print("计算,算个123")
print("CPU对象",self)
class Screen:
def show(self):
print("显示一个好看的画面")
print("屏幕对象:",self)
c = CPU()
s = Screen()
m = MobilePhone(c,s)
m.cpu.calculate()
n = m
print(m,n) # m 跟 n 只是引用 他们指向同一个对象的
print('='*20)
m2 = copy.copy(m)
print(m,m2) # 浅拷贝 地址不同了
m.cpu.calculate() # 浅拷贝 子对象地址还是一样
m2.cpu.calculate() # 浅拷贝 子对象地址还是一样
print('='*20)
m3 = copy.deepcopy(m)
m3.cpu.calculate()
m.cpu.calculate()
将若干不同的类组合到一起就可以实现复杂功能了。
工厂模式
class Benz:
pass
class BMW:
pass
class BYD:
pass
class CarFactory:
@staticmethod
def createCar(name):
if name == "奔驰":
return Benz()
elif name == "宝马":
return BMW()
elif name == "比亚迪":
return BYD()
else:
return "未知品牌"
c1 = CarFactory.createCar("宝马")
c2 = CarFactory.createCar("奔驰")
单例模式
单例模式只生成一个实例对象,减少了对系统资源的开销,当一个对象的产生需要较多资源,如读取配置文件,产生其他依赖对象时,可以产生一个单例对象,永久驻留内存。降低开销。
#coding=utf-8
import time
import math
import copy
import threading
class MySingleton:
__instance_lock = threading.Lock()
def __init__(self,name):
if MySingleton.__init_flag:
print("init")
self.name = name
MySingleton.__init_flag = False
def __new__(cls, *args, **kwargs):
'''
:param args:
:param kwargs:
:return: 对象创新的时候先调用new 方法 如果类没有写 会调用 object 中的new 方法,然后 再调用 init 方法进行初始化
因此 如果单例模式的话一般也是在此进行设置
'''
print(123)
with MySingleton.__instance_lock:
if cls.__obj == None:
cls.__obj = object.__new__(cls)
print(id(cls.__obj))
return cls.__obj
__obj = None
__init_flag = True
a = MySingleton("aa")
print(id(a))