一.面向对象编程 OOP (Object Oriented Programming)

1.OOP是一种计算机编程架构,计算机程序是由单个能够起到子程序作用的单元或对象组合而成,即把对象作为程序的基本单元。

2.面向对象本身是对面向过程的封装。

3.OOP的三大特点:封装、继承和多态。

4.python是一门彻底的面向对象编程(opp)的语言,python中万物皆对象。

5.python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。

6.python中,一个对象包括:属性和方法(变量+函数)

 

二.类(Class)和实例(Instance)

1.对象:类和实例

(1)类:用来描述具有相同的属性和方法的对象的集合,类本质上也是对象

(2)实例:具有属性和方法的对象,实例本质上也是对象,在python中实例也被称为对象,为了区别于整个的对象概念,把它称作实例

(3)实例抽象出类,类实例化为实例,一个类可以有多个实例

(4)类和实例相当于抽象和具体的关系:比如:类:学生;实例:张三

2.python中默认继承(object)的类,也被称作新式类

3.python中通过一个类对象来创建另一个类对象或对应的实例对象,

4.创建类对象的类被称作元类,type是终极元类

5.类和对象:(1)类=对象=类对象;类属性(2) 对象=对象=一般对象=实例;对象属性=实例属性

 

三.创建类和实例

1.通过class 创建一个类

2.类的创建流程:检测__metaclass__属性:该类--父类--模块中--type元类

3.根据类名实例化一个实例

4.类名(money)是变量(money),变量(类名)引用该类,类实例化对象,由变量(one)引用该对象,由该对象里面的__class__找到该类

python3 面向对象编程
 1 class Money:
 2     pass
 3 one=Money()
 4 print(type(Money))
 5 print(type(one))
 6 print(Money.__name__)#访问类的名称
 7 print(one.__class__)#访问实例对应的类
 8 ----------------------------------------------------------------------
 9 <class 'type'>
10 <class '__main__.Money'>
11 Money
12 <class '__main__.Money'>
创建类和实例

python3 面向对象编程

python3 面向对象编程
 1 #type(cls, what, bases=None, dict=None):
 2 # 创建类:类名=type(类,父类(),{__dict__})
 3 #通过元类创建
 4 a=10
 5 print(type(a))
 6 xxx=type('dog',(),{'count':0})
 7 print(xxx)
 8 print(xxx.__dict__)
 9 d=xxx()
10 print(d)
11 -------------------------------------------
12 <class 'int'>
13 <class '__main__.dog'>
14 {'count': 0, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'dog' objects>, '__weakref__': <attribute '__weakref__' of 'dog' objects>, '__doc__': None}
15 <__main__.dog object at 0x0307C4B0>
类对象的创建方式2

 

四.属性

1.类属性和实例属性

(1)类属性:定义在类中且在函数体之外,可以通过类名访问其属性;类属性被对应的各个实例中共享;类属性通常不作为实例属性使用

(2)实例属性:定义在方法中的属性,只作用于当前实例的类

(3)类对象的__dict__属性(只读属性)默认不能被赋值修改,可以通过setattr方法修改;而一般对象里面的__dict__属性能被直接修改

(4)一般情况下,属性存储在__dict__的字典中,有些内置对象没有这个__dict__属性

(5)能通过实例找到类属性,不能通过类访问实例属性

(6)变量后面加_:表示与系统关键字进行区分的命名方式;变量后面加__:表示系统内置的写法

(7)实例属性访问机制:getattribute方法---调用描述器方法的get方法---实例自身的dict字典---对应类的dict字典---父类(上层)的dict字典---调用getattr方法

python3 面向对象编程

2.类属性的增、删、改、查

python3 面向对象编程
 1 class money:
 2     age=19
 3     num=123  #直接在类中添加属性
 4 money.count=1#给类增加一些属性,类属性=值
 5 money.age=3#给类的属性直接赋值;来改变属性值
 6 print(money.count)
 7 print(money.age)
 8 print(money.__dict__)#查看类的所有属性,以字典形式返回(类的内置属性和创建的属性)
 9 
10 m=money
11 print(m.age)#通过对象访问类的属性
12 print(m.__name__)
13 print(m.__class__)
14 
15 #del 删除类的直系属性
16 #不能通过对象删除累属性
17 -----------------------------------------------------
18 1
19 3
20 {'__module__': '__main__', 'age': 3, 'num': 123, '__dict__': <attribute '__dict__' of 'money' objects>, '__weakref__': <attribute '__weakref__' of 'money' objects>, '__doc__': None, 'count': 1}
21 3
22 money
23 <class 'type'>
24 
25 类属性
类属性的增、删、改、查

3.实例属性的增、删、改、查

python3 面向对象编程
 1 class Person:
 2     pass
 3 p=Person()
 4 
 5 #给p对象增加一些属性,对象属性=值
 6 p.age=18
 7 #验证是否有添加成功
 8 print(p.age)
 9 print(p.__dict__)#查看对象的所有属性,以字典形式返回
10 
11 p.age=[1,3]#修改操作,直接赋值修改对象的属性,id会变
12 print(p.age)
13 
14 p.age.append('小花')#访问操作,操作(添加)值,id不变
15 print(p.age)
16 
17 #del 删除
18 ---------------------------------------------------------
19 18
20 {'age': 18}
21 [1, 3]
22 [1, 3, '小花']
实例属性的增、删、改、查

4.限制实例属性的添加__slots__

python3 面向对象编程
1 class person:
2     __slots__ = ['age']#限制对象属性的添加
3     pass
4 p1=person()
5 p1.age=10
6 # p1.num=10 报错AttributeError: 'person' object has no attribute 'num'
7 print(p1.age)
8 ----------------------------------------------
9 10
限制对象属性的添加__slots__

5.python中对象的属性查找机制:优先到对象自身去查找属性,找到则结束;如果没找到,则根据__class__找到对象对应的类,到类里面查找

6.公有属性、受保护属性、私有属性

(1)公有属性:共享的属性,一般的属性

(2)受保护属性:受到保护的属性,用 _ 前缀表示

(3)私有属性:防止外界直接访问,防止被子类同名称属性覆盖,进行数据保护和数据过滤,用 __ 前缀表示,实例不能访问私有属性

python3 面向对象编程
 1 class person:
 2     def __init__(self):
 3         self.__age=18
 4 
 5     def setAge(self,value):
 6         if isinstance(value,int) and 0<value<200:#数据过滤
 7             self.__age=value
 8         else:
 9             print('数据错误')
10 
11     def getAge(self):
12         return self.__age
13 
14 p=person()
15 print(p._person__age)
16 p.setAge(20)
17 print(p._person__age)
18 print(p.getAge())
19 -------------------------------------------------
20 18
21 20
22 20
私有化属性

 私有属性的访问(名字重整):__类名 变为 _类名__x

python3 面向对象编程
 1 class Animal:
 2     __x = 10
 3     def test(self):
 4         print(Animal.__x)
 5         print(self.__x)
 6 
 7 print(Animal.__dict__)
 8 print(Animal._Animal__x)
 9 -------------------------------------------------
10 {'__module__': '__main__', '_Animal__x': 10, 'test': <function Animal.test at 0x0304C618>, '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>, '__doc__': None}
11 10
私有属性名称重整

python3 面向对象编程

7.只读属性(只能读取,不能写入):(1)先私有化,再部分公开,;利用@property装饰器(2)__setattr__

python3 面向对象编程
 1 class Person:
 2     def __init__(self):
 3         self.__age=18
 4 
 5     def getAge(self):
 6         return self.__age
 7 
 8     @property  # 可以将一些属性的操作方法关联这个方法
 9     # property(fget=Nofne, set=None, fdel=None, doc=None)
10     def age(self):
11         return self.__age
12 p=Person()
13 print(p.getAge())
14 print(p.age)
15 # p.age=666 #AttributeError: can't set attribute
16 -------------------------------------------------------------
17 18
18 18
只读属性1
python3 面向对象编程
 1 class Person:
 2     def __setattr__(self, key, value):
 3         print(key, value)
 4         if key=='age'and key in self.__dict__.keys():
 5             print('只读属性')
 6         else:
 7             self.__dict__[key]=value
 8 
 9 p=Person()
10 p.age=19
11 p.name='sz'
12 print(p.__dict__)
13 print(p.age)
14 p.age=12
15 print(p.age)
16 -------------------------------------------
17 age 19
18 name sz
19 {'age': 19, 'name': 'sz'}
20 19
21 age 12
22 只读属性
23 19
只读属性2

 

五.方法

1.在类内部,使用 def 关键字来定义一个方法;调用:对象.方法

2.与一般函数定义不同,方法必须包含形式参数 self, 且为第一个参数,self 代表的是对象本身

3.self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类,self 不是 python 关键字,可以认为方法中的self其实就是实例对象的唯一标志

4.实例方法、类方法、静态方法

(1)无论哪种类型的方法,都是存储在类中,在类的__dict__指向的字典中,没有在实例当中的方法

python3 面向对象编程
 1 class person:
 2     def shilifangfa(self):
 3         print('实例方法',self)
 4 
 5     @classmethod
 6     def leifangfa(cls):
 7         print('类方法',cls)
 8 
 9     @staticmethod
10     def jingtaifanggfa():
11         print('静态方法')
12 
13 p=person()
14 p.shilifangfa()
15 print(p)
16 # person.shilifangfa()#TypeError: shilifangfa() missing 1 required positional argument: 'self'
17 
18 person.leifangfa()
19 person.jingtaifanggfa()
20 -----------------------------------------------------------------
21 实例方法 <__main__.person object at 0x052B6070>
22 <__main__.person object at 0x052B6070>
23 类方法 <class '__main__.person'>
24 静态方法
定义在类中的方法

(2)实例方法:默认第一个参数需要接受到一个实例;调用:对象.方法

(3)类方法:默认第一个参数需要接受到一个类,绑定在类上的方法

python3 面向对象编程
 1 class Person:
 2     @classmethod#类方法装饰器
 3     def leifangfa(cls,a):#第一个参数默认为类
 4         print('类方法',cls,a)
 5 
 6 Person.leifangfa(123)#通过类来调用
 7 p=Person()
 8 p.leifangfa(666)#通过实例来调用
 9 
10 func=Person.leifangfa#通过定义函数的形式来调用
11 func(111)
12 
13 class A(Person):
14     pass
15 A.leifangfa(1)#通过衍生类来调用
16 ----------------------------------------------------------
17 类方法 <class '__main__.Person'> 123
18 类方法 <class '__main__.Person'> 666
19 类方法 <class '__main__.Person'> 111
20 类方法 <class '__main__.A'> 1
21 
22 类方法
类方法的调用

(4)静态方法:第一个参数什么也不默认接受;

python3 面向对象编程
 1 class Person:
 2     @staticmethod#静态方法装饰器
 3     def jingtai():
 4         print('静态方法')
 5 
 6 Person.jingtai()#通过类来调用
 7 p=Person()
 8 p.jingtai()#通过实例来调用
 9 func=Person.jingtai#通过定义函数的形式来调用
10 func()
11 ------------------------------------------
12 静态方法
13 静态方法
14 静态方法
静态方法

(5)三种方法的访问权限

python3 面向对象编程
 1 class Person:
 2     age=5
 3     def shilifangfa(self):
 4         print('实例方法',self)
 5         print(self.age)
 6         print(self.num)
 7 
 8     @classmethod
 9     def leifangfa(cls):
10         print('类方法',cls)
11         print(cls.age)
12         print(cls.num)
13     @staticmethod
14     def jingtaifanggfa():
15         print('静态方法')
16         print(Person.age)#访问类属性
17 
18 p=Person()
19 p.num=10
20 p.shilifangfa()#实例方法既能访问实例属性,又能访问类属性
21 
22 # p.leifangfa()#AttributeError: type object 'Person' has no attribute 'num'
23 #Person.leifangfa()#AttributeError: type object 'Person' has no attribute 'num'
24 #类方法不能访问实例属性,但能访问类属性
25 
26 Person.jingtaifanggfa()
27 #静态方法可以访问类属性,但不能访问实例属性
28 --------------------------------------------------------------------
29 实例方法 <__main__.Person object at 0x054B6170>
30 5
31 10
32 静态方法
33 5
三种方法的访问

5.类的私有方法__private_method(相似私有属性):声明该方法为私有方法,只能在类的内部调用 ,不能在类地外部调用,self.__private_methods

6.类的特殊方法

(1)init初始化

python3 面向对象编程
 1 class myclass:
 2     """一个简单是实例"""
 3     i=21313
 4     def f(self):
 5         return 'hello world'
 6 
 7 #__init__()将对象创建为有初始状态的
 8 #类定义了 __init__() 方法的话,类的实例化操作会自动调用 __init__() 方法
 9 # __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上
10     def __init__(self,realpart):
11         self.r = realpart
12 
13 
14 x=myclass(3.4)   # 实例化类
15 print(x.r)
16 print(x.f)
17 ------------------------------------------------------------------
18 3.4
19 <bound method myclass.f of <__main__.myclass object at 0x057C73D0>>
init()

(2)信息格式化操作,用字符串描述实例:__str__和__repr__

python3 面向对象编程
 1 class person:
 2     def __init__(self,n,a):
 3         self.name=n
 4         self.age=a
 5     def __str__(self):#信息格式化,用字符串描述实例,面向用户,通过print或str触发
 6         return '姓名:{},年龄:{}'.format(self.name,self.age)
 7     def __repr__(self):#信息格式化,用字符串描述实例,面向开发人员,通过实例本身或repr触发
 8         return 'repr'
 9 #先找__str__,如果没有,再找__repr__
10 p=person('sz',18)
11 print(p.name)
12 print(p,type(p))#方法里的返回值#没有__str__方法时<__main__.person object at 0x04C86070>
13 print(str(p),type(str(p)))#字符串
14 print(repr(p))#获取实例的本质信息,可以用eval再次转换
15 -------------------------------------------
16 sz
17 姓名:sz,年龄:18 <class '__main__.person'>
18 姓名:sz,年龄:18 <class 'str'>
19 repr
str和repr

(3)调用操作:__call__方法,使对象具备当做函数来调用的能力

python3 面向对象编程
 1 class person:
 2     def __init__(self,name):
 3         self.name=name
 4     def __call__(self,age):
 5         print('姓名:{},年龄:{}'.format(self.name,age))
 6 
 7 
 8 p=person('zyl')
 9 p(28)#使实例能被调用,传入参数
10 p(23)
11 p(14)
12 ---------------------------------------------
13 姓名:zyl,年龄:28
14 姓名:zyl,年龄:23
15 姓名:zyl,年龄:14
__call__

(4)索引操作:对一个实例进行索引,三个内置方法:setitem,getitem,delitem

python3 面向对象编程
 1 class person:
 2     def __init__(self):
 3         self.cache={}#增加一个字典属性
 4     def __setitem__(self, key, value):#设置/增添键值
 5         print('setitem',key,value)
 6         self.cache[key]=value
 7 
 8     def __getitem__(self, item):#获取键值
 9         # print('getitem',item)
10         return self.cache[item]
11 
12     def __delitem__(self, key):#删除操作
13         # print('setitem',key)
14         del self.cache[key]
15 
16 
17 p=person()
18 p['name']='sz'#setitem
19 print(p['name'])#getitem
20 del p['name']
21 print(p.cache)#查询字典
22 ---------------------------------------------------
23 setitem name sz
24 sz
25 {}
索引

(5)切片操作:对一个实例进行切片操作,三个内置方法:setitem,getitem,delitem

python3 面向对象编程
 1 class person:
 2     def __init__(self):
 3         self.items=[1,2,3,4,5,6,7,8,]#初始化以列表形式
 4     def __setitem__(self, key, value):#切片时只能修改,不能新增
 5         print(key,value)
 6         print(key.start)
 7         print(key.stop)
 8         print(key.step)
 9         self.items[key]=value
10         #if isinstance(key,slice):#容错处理
11         #    self.items[key.start:key.stop:key.step]=value
12 
13     def __getitem__(self, item):#获取信息
14         print('getitem',item)
15 
16     def __delitem__(self, key):#删除
17         print('setitem',key)
18 
19 
20 p=person()
21 print(p)
22 print(p.items)
23 p[0:4:2]=['a','b']#对进行切片操作,修改列表
24 print(p.items)
25 -------------------------------------------------------------------
26 <__main__.person object at 0x0352C4B0>
27 [1, 2, 3, 4, 5, 6, 7, 8]
28 slice(0, 4, 2) ['a', 'b']
29 0
30 4
31 2
32 ['a', 2, 'b', 4, 5, 6, 7, 8]
切片

(6)比较操作:比较大小,真假

python3 面向对象编程
 1 class person:
 2     def __init__(self,age,height):
 3         self.age=age
 4         self.height=height
 5     def __eq__(self, other):#实现相等操作
 6         print(other)
 7         return self.age==other.age#返回操作后的值
 8     def __ne__(self, other):#不相等
 9         print('xxx')
10     def __gt__(self, other):#大于
11         pass
12     def __ge__(self, other):#大于等于
13         pass
14     def __lt__(self, other):#小于
15         print('lt')
16     def __le__(self, other):#小于等于
17         pass
18     def __bool__(self):#布尔类型,返回实例是True还是False
19         return self.age>18#返回值控制实例是True还是False
20 
21 
22 p1=person(18,180)
23 p2=person(17,190)
24 print(p1==p2)
25 print(p1!=p2)
26 print(p1<p2)
27 -------------------------------------------------
28 <__main__.person object at 0x059A60D0>
29 False
30 xxx
31 None
32 lt
33 None
比较

(7)遍历操作:getitem、iter、next,类中同时有iter和next方法的实例才是一个迭代器,利用iter获取迭代器对象,利用next访问迭代器

python3 面向对象编程
 1 class person:
 2     def __init__(self):
 3         self.result=1
 4     def __getitem__(self, item):
 5         self.result+=1
 6         if self.result>=6:
 7             raise StopIteration('停止遍历')
 8         return self.result
 9 
10 p=person()
11 for i in p:
12     print(i)
13 --------------------------------------------
14 2
15 3
16 4
17 5
getitem
python3 面向对象编程
 1 class person:
 2     def __init__(self):
 3         self.result=1
 4 # iter优先级高于getitem
 5     def __iter__(self):#获取实例的迭代器
 6         print('iter')
 7         return self#返回是一个迭代器对象
 8     def __next__(self):#对于迭代器调用next方法
 9         self.result+=1
10         if self.result>=6:
11             raise StopIteration('停止遍历')
12         return self.result#对于迭代器进行遍历
13 p=person()
14 for i in p:
15     print(i)
16 --------------------------------------------
17 iter
18 2
19 3
20 4
21 5
iter

(8)描述器:可以描述一个属性操作的对象;property用来管理属性访问。资料描述器(get/set)>实例属性>非资料描述器(get)

python3 面向对象编程
 1 class Person(object):
 2     def __init__(self):
 3         self.__age=18
 4     def get_age(self):
 5         return self.__age
 6     def set_age(self,value):
 7         self.__age=value
 8     #property(fget=None, fset=None, fdel=None, doc=None)
 9     age=property(get_age,set_age)
10 p=Person()
11 print(p.age)
12 p.age=98
13 print(p.age)
14 print(p.__dict__)
15 
16 
17 
18 class Person2(object):
19     def __init__(self):
20         self.__age=18
21     @property
22     def age(self):
23         return self.__age
24     @age.setter
25     def age(self,value):
26         self.__age=value
27 p2=Person2()
28 print(p2.age)
29 p2.age=98
30 print(p2.age)
31 print(p2.__dict__)
32 ----------------------------------------------------------------------
33 18
34 98
35 {'_Person__age': 98}
36 18
37 98
38 {'_Person2__age': 98}
property
python3 面向对象编程
 1 class Age:
 2     def __get__(self, instance, owner):
 3         print('get')
 4     def __set__(self, instance, value):
 5         print('set')
 6     def __delete__(self, instance):
 7         print('delete')
 8 class person:
 9     age=Age()#描述器
10     def __getattribute__(self, item):
11         print('xxx')
12 
13 #通过实例操作描述器
14 p=person()
15 p.age=10#调用了set,get
16 print(p.age)#调用的方法中没有返回值
17 del p.age#调用了delete
18 #一般不通过类来操作描述器
19 print(person.age)#只是调用了get方法
20 person.age=19
21 del person.age#没有用delete方法
22 ---------------------------------------------------------------------
23 set
24 xxx
25 None
26 delete
27 get
28 None
描述器

 python3 面向对象编程python3 面向对象编程

python3 面向对象编程

 python3 面向对象编程

python3 面向对象编程

python3 面向对象编程

python3 面向对象编程

python3 面向对象编程

python3 面向对象编程

python3 面向对象编程

 7.补充

(1)__new__方法:创建实例对象,将对象创建出来,返回实例对象,主要用于继承一些不可变的类,一般默认

(2)__init__方法:初始化实例对象,一般用于定义初始化属性,当对象被创建,自动执行,无需返回值,若还有new方法,则执行new

(3)__call__方法:使得类能像函数那样调用,一般放类的执行

 

六.继承

class DerivedClassName(BaseClassName):
       <statement>


class DerivedClassName(modname.BaseClassName):

       <statement>

其中DerivedClassName子类     BaseClassName基类

python3 面向对象编程
 1 class people:                   # 类定义
 2     name = ''                   # 定义基本属性
 3     age = 0                     # 定义基本属性
 4     __weight = 0                # 定义私有属性,私有属性在类外部无法直接进行访问
 5 
 6     def __init__(self, n, a, w):# 定义构造方法
 7         self.name = n
 8         self.age = a
 9         self.__weight = w
10 
11     def speak(self):            # 定义构造方法
12         print("%s 说: 我 %d 岁。" % (self.name, self.age))
13 
14 class student(people):          # 单继承示例,定义基类
15     grade = ''
16 
17     def __init__(self, n, a, w, g):
18         people.__init__(self, n, a, w)# 调用父类的构函
19         self.grade = g
20 
21     def speak(self):            # 覆写父类的方法
22         print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
23 
24 class speaker():                # 另一个类,多重继承之前的准备
25     topic = ''
26     name = ''
27 
28     def __init__(self, n, t):
29         self.name = n
30         self.topic = t
31 
32     def speak(self):
33         print("我叫 %s,我是一个演说家,我演讲的主题是 %s" % (self.name, self.topic))
34 
35 # 多重继承
36 class sample(speaker, student):
37     a = ''
38 
39     def __init__(self, n, a, w, g, t):
40         student.__init__(self, n, a, w, g)
41         speaker.__init__(self, n, t)
42 
43 
44 test = sample("Tim", 25, 80, 4, "Python")
45 test.speak()  # 方法名同,默认调用的是在括号中排前地父类的方法
46 ------------------------------------------------------------------------------
47 我叫 Tim,我是一个演说家,我演讲的主题是 Python
继承

1.子类(派生类)继承父类(超类)(基类):子类拥有父类一些资源的'使用权'

2.父类---共性;子类---特性

3.单继承:仅仅继承一个父类;多继承:继承多个父类;多继承分为无重叠的多继承,有重叠的多继承python3 面向对象编程

4.可以在子类中重写父类的方法

5.supper()调用父的一个方法,自动找到所有基类以及对应的方法

python3 面向对象编程
 1 class Dongwu():
 2     def __init__(self,name):
 3         self.name=name
 4     def shengming(self):
 5         print('dongwu')
 6 
 7 class Gou(Dongwu):
 8     def __init__(self,name,color):
 9         super().__init__(name)  #调用父类的一个方法,从父类获得继承
10         self.color=color        #在子类中添加新的内容
11     def shengming(self):
12         print('gou')
13     def kanjia(self):
14         print('kanjia')
15 
16 a1=Dongwu('a1')
17 a2=Gou('a2',1)
18 print(a1.shengming(),a2.shengming())
19 ----------------------------------------------------------------------------
20 dongwu
21 gou
super
python3 面向对象编程
 1 class D:
 2     def __init__(self):
 3         print('d')
 4 class B(D):
 5     def __init__(self):
 6         D.__init__(self)#调用父类的方法
 7         print('b')
 8 class C(D):
 9     def __init__(self):
10         super().__init__()
11         print('c')
12 class A(C,B):
13     def __init__(self):
14         # B.__init__(self)
15         # C.__init__(self)调用了两次
16         #super沿着mro链条,找到下一级节点,去调用对应的方法
17         #super(__class__, <first argument>)沿着参数二的mro链条,找参数一的下一个节点
18         #使用参数二进行调用
19         super(A, self).__init__()
20         # super().__init__()
21         print('a')
22 C()
23 A()
24 -------------------------------------
25 d
26 c
27 d
28 b
29 c
30 a
super

6.type和object

(1)type:元类,实例化其他类,包括object类,type类实例化object类

(2)object:所有类的父类,包括type类,type类继承object类

7.资源:除了私有的方法和属性,其他的基本都能继承;资源的‘使用权’实质上指资源的访问权,并不是指资源的复制

8.资源的使用:

(1)单继承链:从下到上

(2)无重叠的多继承链:从左到右,从上到下

(3)有重叠的多继承链:从上到下,从左到右,(新式类,c3算法)

python3 面向对象编程
 1 #查看资源查找顺序
 2 import inspect
 3 class animal:
 4     pass
 5 class person(animal):
 6     pass
 7 inspect.getmro(person)#查看类资源的访问循序
 8 print(person.__mro__)
 9 print(person.mro())
10 ---------------------------------------------------------------
11 (<class '__main__.person'>, <class '__main__.animal'>, <class 'object'>)
12 [<class '__main__.person'>, <class '__main__.animal'>, <class 'object'>]
资源查找
python3 面向对象编程
 1 class D:
 2     pass
 3 class B(D):
 4     pass
 5 class C(D):
 6     pass
 7 class A(C,B):
 8     pass
 9 print(A.mro())
10 -----------------------------------------------
11 [<class '__main__.A'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.D'>, <class 'object'>]
资源查找

9.资源的覆盖:属性的覆盖和方法的重写;本质是访问优先级顺序决定的

 

七.内存管理机制

1.所有对象都会在内存中开辟一块空间进行存储;根据不同的类型及内容开辟不同的空间大小进行存储,并返回该空间的地址给外界接受(引用),用于后续对这个对象的操作

2.对于整数和短小的字符,python会进行缓存,不会创建多个相同对象

3.容器对象(列表,元组,字典,自定义类对象等),存储的其他对象,仅仅是其他对象的引用,并不是其他对象本身

4.引用计数器:对象自身被引用的个数

python3 面向对象编程
 1 import sys
 2 class person:
 3     pass
 4 p1 = person()  # p1引用person类对象====把person类对象的地址赋值给p1
 5 print(sys.getrefcount(p1))#查看p1引用的对象的引用个数,注意初始为一即结果是:实际引用个数加一
 6 p2 = p1#把p1的值赋值给p2,p1的值是person类对象的地址,p2引用person类对象,p2的值是person类对象的地址
 7 print(sys.getrefcount(p1))  # 查看对象(person类对象)引用个数,注意初始为一即结果是:实际引用个数加一
 8 del p2
 9 print(sys.getrefcount(p1)) #查看p1引用的对象的引用个数
10 
11 #引用计数加一:
12 #p1=person()对象被创建
13 p2=p1#对象被引用,3
14 print(sys.getrefcount(p1))
15 l=[p1]#对象作为一个元素存储在容器中,引用次数加一,4
16 print(sys.getrefcount(p1))
17 
18 # 引用次数+2
19 def log(obj):
20     print(sys.getrefcount(obj))
21 log(p1)#对象被作为参数,传入到一个函数中,6
22 
23 #引用次数减一:
24 #del p1对象的别名被显示销毁
25 #p1 = 123 对象的别名被赋予新的对象
26 #一个对象离开它的作用域:一个函数执行完毕时;内部的局部变量关联的对象,它的引用会被释放
27 #对象所在的容器被销毁,或从容器中删除对象
28 ---------------------------------------------------------------------
29 2
30 3
31 2
32 3
33 4
34 6
引用计数器
python3 面向对象编程
 1 #循环引用
 2 import objgraph
 3 class person:
 4     pass
 5 class dog:
 6     pass
 7 
 8 p=person()
 9 d=dog()
10 print(objgraph.count('person'))#垃圾回收器,查看跟踪的对象个数
11 print(objgraph.count('dog'))
12 p.pet=d
13 d.master=p
14 print(objgraph.count('person'))
15 print(objgraph.count('dog'))
16 
17 del p
18 del d
19 print(objgraph.count('person'))#对象并没有被释放
20 print(objgraph.count('dog'))
21 -----------------------------------------------------------------
22 1
23 1
24 1
25 1
26 1
27 1
循环引用

5.垃圾回收机制:解决循环引用问题:找到循环引用并干掉相关对象

python3 面向对象编程
 1 #垃圾回收机制
 2 #找到循环引用
 3 #1.收集所有容器对象,通过一个双向链表进行引用
 4 #2.对于每一个‘容器对象’,通过gc_refs来记录当前对应的引用计数
 5 #3.对于每一个‘容器对象’,找到它引用的‘容器对象’,并将这个‘容器对象’的引用计数-1
 6 #4.通过引用计数判断是否是循环引用,计数器为0的为循环引用,可以被释放
 7 
 8 
 9 #垃圾回收器中,新增的对象个数-消亡的个数达到一定阈值是才会触发垃圾检测
10 #垃圾回收的周期顺序:0代垃圾回收一定次数才会触发0,1代回收;1代垃圾回收一定次数才会触发0,1,2代回收
11 import gc
12 import objgraph
13 print(gc.get_threshold())#得到垃圾检测的参数(阈值,10代,10代)
14 gc.set_threshold(800,10,10)#设置垃圾检测的参数
15 print(gc.get_threshold())
16 
17 #垃圾回收:
18 #自动回收:开启垃圾回收机制;达到垃圾回收的阈值
19 print(gc.isenabled())#检测垃圾回收机制是否开启
20 gc.disable()#关闭垃圾回收机制
21 print(gc.isenabled())
22 gc.enable()#开启垃圾回收机制
23 print(gc.isenabled())
24 
25 #手动回收:
26 class person:
27     def __del__(self):
28         print('person对象被释放了')
29 class dog:
30     def __del__(self):
31         print('dog对象被释放了')
32 p=person()
33 d=dog()
34 #两个实例对象之间相互引用,造成循环引用
35 p.pet=d
36 d.master=p#python2中弱引用weakref.ref()
37 del p
38 del d
39 gc.collect()#手动回收垃圾,无关垃圾自动清理机制是否开启
40 print(objgraph.count('person'))
41 print(objgraph.count('dog'))
42 --------------------------------------------------------------------
43 (700, 10, 10)
44 (800, 10, 10)
45 True
46 False
47 True
48 person对象被释放了
49 dog对象被释放了
50 0
51 0
垃圾回收机制

 

八.补充

1.如果对象的属性和方法名相同,属性会覆盖方法

1.封装:把操作和属性封装在一个对象中

2.多态:对象行为和属性的多态;python中并没有真正的多态,也不需要多态

3.一个迭代器一定是一个可迭代对象,一个可迭代对象不一定是迭代器;可迭代对象:iter;迭代器:iter和next

4.重载

python3 面向对象编程
 1 class Dw():
 2     def __init__(self,name):
 3         self.name=name
 4 #<__main__.Dw object at 0x02BD73D0>
 5     
 6    def __str__(self):
 7         return self.name
 8 #a
 9    
10    def __repr__(self):
11         return 'name:' +self.name
12 #name:a
13 
14 a=Dw('a')
15 print(a)
16 ------------------------------------------------
17 a
重载

5.组合:直接在类定义中把需要的类放进去实例化

python3 面向对象编程
 1 #组合:把类和实例化方方放到新类中,把几个没有关系的类放到一起
 2 class Turtle:
 3     def __init__(self,x):
 4         self.num=x
 5 class Fish:
 6     def __init__(self,x):
 7         self.num = x
 8 class Pool:
 9     def __init__(self,x,y):
10         self.turtle=Turtle(x)
11         self.fish=Fish(y)
12     def print_num(self):
13         print(self.turtle.num,self.fish.num)
14 
15 pool=Pool(1,10)
16 pool.print_num()
17 ----------------------------------------------------------------------
18 1 10
组合

6.生成项目文档pydoc:(1):cmd--转到查看python文件的目录;查看文档描述: python -m pydoc 模块名称

     (2)启动本地服务,浏览web文档:python -m pydoc -p 端口号

     (3)生成指定模块html文档 :  python -m pydoc -w 模块名称

     (4)-k 查看相关的模块

      (5)-h帮助文档python -m pydoc -h 模块

     (6)-b自己开启端口python -m pydoc -b

7.抽象类和抽象方法:抽象类:抽象出来的类,不能直接创建实例的类,创建会报错;抽象方法:抽象出来的方法,不具备具体实现,不能直接调用,子类不实现会报错

python3 面向对象编程
 1 import abc
 2 class animal(object,metaclass=abc.ABCMeta):
 3     @abc.abstractmethod
 4     def jiao(self):
 5         pass
 6 class dog(animal):
 7     def jiao(self):
 8         print('wang')
 9 
10 class cat(animal):
11     def jiao(self):
12         print('miao')
13 
14 def test(obj):
15     obj.jiao()
16 
17 d=dog()
18 d.jiao()
19 --------------------------------------
20 wang
抽象

 

相关文章: