python 面向对象基础
一、三大编程范式
编程范式即编程的方法论,标识一种编程风格
三大编程范式:
1.面向过程编程
2.函数式编程
3.面向对象编程
二、编程进化论
1.编程最开始就是无组织无结构,从简单控制流中按步写指令
2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比方说,你定义了一个函数),便实现了代码重用,且代码由无结构走向了结构化,创建程序的过程变得更具逻辑性
3.我们定义函数都是独立于函数外定义变量,然后作为参数传递给函数,这意味着:数据与动作是分离的
4.如果我们把数据和动作内嵌到一个结构(函数或类)里面,那么我们就有了一个‘对象系统’(对象就是数据与函数整合到一起的产物)。
1 假设你是一条狗,我们用结构化的数据来描述你 2 1:数据与动作分离 3 2:数据与动作结合 4 5 导向: 6 1.面向对象设计 7 2.什么是类什么是对象
三、面向对象设计与面向对象编程
def定义函数是面向对象
class定义类是面向对象
1、面向对象设计
面向对象设计(Object oriented design):将一类具体事物的数据和动作整合到一起,即面向对象设计
示例1:
1 #相当于:类 2 def dog(name,gender,type): 3 #狗的动作 4 def jiao(dog): 5 print('一条狗[%s],汪汪汪' % dog['name']) 6 def chi_shi(dog): 7 print('一条[%s] 正在吃肉' % dog['type']) 8 #狗的属性 9 def init(name,gender,type): 10 dog1 = { 11 'name':name, 12 'gender':gender, 13 'type':type, 14 'jiao':jiao, #动作 15 'chi_shi':chi_shi, #动作 16 } 17 return dog1 18 return init(name,gender,type) 19 20 d1=dog('元吴','母','中华犬') 21 d2=dog('alex','母','藏敖') 22 print(d1) 23 print(d2) 24 d1['jiao'](d1) 25 d2['chi_shi'](d2)
什么是类?
类:把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念。
什么是对象?
对象:就是基于类而创建的一个具体的事物(指具体存在的),也是特征和动作整合到一起。
示例2:
学校类:
特征:name,addr,type
动作:考试,招生,开除学生
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #Author: nulige 4 5 def school(name,addr,type): 6 def init(name, addr, type): 7 sch = { 8 'name': name, 9 'addr': addr, 10 'type': type, 11 'kao_shi': kao_shi, 12 'zhao_sheng': zhao_sheng, 13 } 14 return sch 15 def kao_shi(school): 16 print('%s 学校正在考试' %school['name']) 17 def zhao_sheng(school): 18 print('%s %s 正在招生' %(school['type'],school['name'])) 19 return init(name,addr,type) 20 21 s1=school('oldboy','沙河','私立学校') 22 print(s1) 23 print(s1['name']) 24 25 s1['zhao_sheng'](s1) 26 27 s2=school('清华','北京','公立学校') 28 29 print(s2) 30 print(s2['name'],s2['addr'],s2['type']) 31 s2['zhao_sheng'](s2)
2、面向对象编程
面向对象编程(object-oriented programming):用定义类+实例/对象的方式去实现面向对象的设计
1 #用面向对象编程独有的语法class去实现面向对象设计 2 class Dog: 3 def __init__(self,name,gender,type): #实例化的过程,就是运行__init__ 4 self.name=name 5 self.gender=gender 6 self.type=type 7 8 def bark(self): 9 print('一条名字为[%s]的[%s],狂吠不止' %(self.name,self.type)) 10 11 def yao_ren(self): 12 print('[%s]正在咬人' %(self.name)) 13 14 def chi_shi(self): 15 print('[%s]正在吃屎' %(self.type)) 16 17 dog1=Dog('alex','female','京巴') 18 dog2=Dog('wupeiqi','female','腊肠') 19 dog3=Dog('yuanhao','female','藏獒') 20 21 dog1.bark() 22 dog2.yao_ren() 23 dog3.chi_shi()
小结:
在Python中,类和 OOP 都不是日常编程所必需的。尽管它从一开始设计就是面向对象的,并且结构上支持 OOP,但 Python 没有限定或要求你在你的应用中写 OOP 的代码。
用面向对象语言写程序和一个程序的设计是面向对象的,两者就是两码事。
四、类和对象
1.什么叫类:类是一种数据结构,就好比一个模型,该模型用来表述一类事物(事物即数据和动作的结合体),用它来生产真实的物体(实例)。
2.什么叫对象:睁开眼,你看到的一切的事物都是一个个的对象,你可以把对象理解为一个具体的事物(事物即数据和动作的结合体)
(铅笔是对象,人是对象,房子是对象,狗是对象,alex是对象,配齐是对象,元昊是对象)
3.类与对象的关系:对象都是由类产生的,上帝造人,上帝首先有一个造人的模板,这个模板即人的类,然后上帝根据类的定义来生产一个个的人
4.什么叫实例化:由类生产对象的过程叫实例化,类实例化的结果就是一个对象,或者叫做一个实例(实例=对象)
五、类的相关知识
1、初识类
在python中声明函数与声明类很相似。
声明函数
1
2
3
|
1 def functionName(args):
2 '函数文档字符串'
3 函数体
|
声明类
1 ''' 2 class 类名: 3 '类的文档字符串' 4 类体 5 ''' 6 7 #我们创建一个类 8 class Data: 9 pass 10 11 #用类Data实例化出一个对象d1 12 d1=Data()
经典类与新式类
1 大前提: 2 1.只有在python2中才分新式类和经典类,python3中统一都是新式类 3 2.新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类 4 3.所有类甭管是否显式声明父类,都有一个默认继承object父类(讲继承时会讲,先记住) 5 在python2中的区分 6 经典类: 7 class 类名: 8 pass 9 10 经典类: 11 class 类名(父类): 12 pass 13 14 在python3中,上述两种定义方式全都是新式类
示例:
1 #经典类(python2.7) 2 class Chinese: 3 '这是一个中国人的类' 4 pass 5 6 print(Chinese) 7 8 #新式类(python3.0) 9 10 #实例化到底干了什么? 11 p1=Chinese() #实例化 12 print(p1)
2、属性
类是用来描述一类事物,类的对象指的是这一类事物中的一个个体
是事物就要有属性,属性分为
1:数据属性:就是变量
2:函数属性:就是函数,在面向对象里通常称为方法
注意:类和对象均用点来访问自己的属性
类的属性
理论:数据属性即变量,类的定义与函数又极其类似,其实可以用函数的作用域来理解类的属性调用。
类的数据属性
1 #定义一个中文人的类,然后在类中定义一个类的属性,*是共产堂,这样,只要是中文人他们的党永远都是共产堂 2 #类属性又称为静态变量,或者是静态数据。这些数据是与它们所属的类对象绑定的,不依赖于任何类实例。 3 #如果你是一位Java或C++程序员,这种类型的数据相当于在一个变量声明前加上static关键字。 4 5 class Chinese: 6 government='共产堂' 7 8 print(Chinese.government)
类的函数属性(又称为方法)
1 class Chinese: 2 government='共产_党' 3 def sui_di_tu_tan(): 4 print('90%的中国人都喜欢随地吐痰') 5 6 def cha_dui(self): 7 print('一个中国人-->%s<--插到了前面' %self) 8 9 Chinese.sui_di_tu_tan() 10 11 person1_obj='alex' 12 Chinese.cha_dui(person1_obj) #带参函数,所以调用时需要传入参数,将'alex'传给self
查看类属性
我们定义的类的属性到底存到哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值
1 #共有属性,动作(方法) 2 class Chinese: 3 '这是一个中国人的类' 4 dang='共产堂' #数据属性 5 def sui_di_tu_tan(): #函数属性 6 print('朝着墙上就是一口痰') 7 def cha_dui(self): #加了self的就必须传一个参数,否则会报错 8 print('插到了前面') 9 10 print(Chinese.dang) 11 Chinese.sui_di_tu_tan() 12 Chinese.cha_dui('元昊') 13 14 # print(dir(Chinese)) #查看系统内置属性 15 # print(Chinese.__dict__) #查看属性字典 16 print(Chinese.__dict__['dang']) #调用数据属性,本身就是在数据属性中找东西 17 Chinese.__dict__['sui_di_tu_tan']() #调用函数属性,有了函数的内存地址,加(),就可以运行 18 Chinese.__dict__['cha_dui'](1) #调用函数属性
执行结果:
1 共产堂 2 在地上就是一口痰 3 插到了前面 4 共产堂 5 在地上就是一口痰 6 插到了前面
特殊的类属性
1 class Chinese: 2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物' 3 government='共产堂' 4 def sui_di_tu_tan(): 5 print('90%的中国人都喜欢随地吐痰') 6 7 def cha_dui(self): 8 print('一个中国人-->%s<--插到了前面' %self) 9 10 print(Chinese.__name__) #类C的名字(字符串) 11 print(Chinese.__doc__) #类C的文档字符串 12 print(Chinese.__base__) #类C的第一个父类(在讲继承时会讲) 13 print(Chinese.__bases__) #类C的所有父类构成的元组(在讲继承时会讲) 14 print(Chinese.__dict__) #类C的属性 15 print(Chinese.__module__)#类C定义所在的模块 16 print(Chinese.__class__) #实例C对应的类(仅新式类中)
六、对象相关知识
对象是由类实例化而来,类实例化的结果称为一个实例或者称作一个对象
1.1、实例化
什么是实例化?
由类生产对象的过程就叫实例化
1 class Chinese: 2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物' 3 government='共产_党' 4 def sui_di_tu_tan(): 5 print('90%的中国人都喜欢随地吐痰') 6 7 def cha_dui(self): 8 print('一个中国人-->%s<--插到了前面' %self) 9 10 person1=Chinese() #类名加上括号就是实例化(可以理解为函数的运行,返回值就是一个实例) 11 12 #这就是实例化,只不过你得到的person1实例,没有做任何事情
1.2、构造函数
类是数据属性和函数属性的结合,描述的是一类事物
这类事物的一个具体表现就是一个实例/对象,比方说中国人是一个类,而你就是这个类的一个实例
你除了有中国人这个数据属性外,还应该有名字,年龄,性别等数据属性
如何为实例定制数据属性,可以使用类的一个内置方法__init__()该方法,在类()实例化是会自动执行
1 class Chinese: 2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物' 3 government='共产_党' 4 def __init__(self,name,age,gender): #实例化的过程可以简单理解为执行该函数的过程,实例本身会当作参数传递给self(这是默认的步骤) 5 self.name=name 6 self.age=age 7 self.gender=gender 8 9 def sui_di_tu_tan(): 10 print('90%的中国人都喜欢随地吐痰') 11 12 def cha_dui(self): 13 print('一个中国人-->%s<--插到了前面' %self) 14 15 # person1=Chinese() #会报错 16 #自动执行__init__方法,而这个方法需要参数, 17 # 这些参数应该写在类名后面的括号里,然后由类传 18 #给__init__函数,也就说,传给类的参数就是传给__init__的参数 19 20 person1=Chinese('alex',1000,'female') 21 person2=Chinese('wupeiqi',10000,'female') 22 person3=Chinese('yuanhao',9000,'female') 23 24 print(person1.__dict__)
注意:在说实例化的时候说过,执行类()会自动返回一值,这个值就是实例,而类()会自动执行__init__,所以一定不要在该函数内定义返回值,会冲突。
1.3、实例属性
理论:
1.实例只有数据属性(实例的函数属性严格来说是类的函数属性)
2.del 实例/对象,只是回收了实例的数据属性,函数属性是属于类的,是不会回收。
实例化的过程实际就是执行__init__的过程,这个函数内部只是为实例本身即self设定了一堆数据(变量),所以实例只有数据属性。
1 class Chinese: 2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物' 3 government='共产_党' 4 def __init__(self,name,age,gender): 5 self.name=name 6 self.age=age 7 self.gender=gender 8 9 def sui_di_tu_tan(): 10 print('90%的中国人都喜欢随地吐痰') 11 12 def cha_dui(self): 13 print('一个中国人-->%s<--插到了前面' %self) 14 15 16 person1=Chinese('alex',1000,'female') 17 print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性 18 print(person1.name,person1.age,person1.gender) #访问实例的数据属性
那么我们想访问实例的函数属性(其实是类的函数属性),如何实现
1 class Chinese: 2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物' 3 government='共产_党' 4 def __init__(self,name,age,gender): 5 self.name=name 6 self.age=age 7 self.gender=gender 8 9 def sui_di_tu_tan(): 10 print('90%的中国人都喜欢随地吐痰') 11 12 def cha_dui(self): 13 print('一个中国人-->%s<--插到了前面' %self) 14 15 16 person1=Chinese('alex',1000,'female') 17 print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性 18 print(Chinese.__dict__)#函数属性只存在于类中 19 Chinese.cha_dui(person1)#我们只能通过类去调用类的函数属性,然后把实例当做变量传递给self
改进版本
1 class Chinese: 2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物' 3 government='共产_党' 4 def __init__(self,name,age,gender): 5 self.name=name 6 self.age=age 7 self.gender=gender 8 9 def sui_di_tu_tan(): 10 print('90%的中国人都喜欢随地吐痰') 11 12 # def cha_dui(self): 13 # print('一个中国人-->%s<--插到了前面' %self) 14 15 def cha_dui(self): 16 print('一个中国人-->姓名:%s 年龄:%s 性别:%s<--插到了前面' %(self.name,self.age,self.gender)) 17 18 def eat_food(self,food): 19 print('%s 正在吃 %s' %(self.name,food)) 20 21 person1=Chinese('alex',1000,'female') 22 print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性 23 print(Chinese.__dict__)#函数属性只存在于类中 24 Chinese.cha_dui(person1)#我们只能通过类去调用类的函数属性,然后把实例当做变量传递给self 25 Chinese.eat_food(person1,'韭菜馅饼') 26 27 28 person1.cha_dui()#其实就是Chinese.cha_dui(person1) 29 person1.eat_food('飞禽走兽') #本质就是Chinese.eat_food(person1,'飞禽走兽')
3、实例属性和查看实例属性的方法如下:
同样是dir和内置__dict__两种方式
原理图
示例:
1 class Chinese: 2 '这是一个中国人的类' 3 4 dang='共产堂' 5 6 def __init__(self,name,age,gender): 7 print('我是初始化函数,我开始运行了') 8 self.mingz=name #name,age,gender都封装在self里面 9 self.nianji=age #p1.nianji=age 10 self.xingbin=gender #p1.xingbin=gender 11 print('我结束啦') 12 13 def sui_di_tu_tan(): 14 print('在地上就是一口痰') 15 def cha_dui(self): 16 print(self) 17 print('%s 插到了前面' %self) 18 #return None (系统默认就是return None,这里不要加return) 19 20 #数据属性 21 p1=Chinese('元昊','18','female') #实例化的过程,就是调用__init__ 22 print(p1.__dict__) #查看字典属性 #==>{'nianji': '18', 'mingz': '元昊', 'xingbin': 'female'} 23 print(p1.mingz) #p1.nianji=age, 直接调用__init__里面的属性, 24 print(p1.dang) #类的作用域概念,如果__init__里面没有,就去外面那层找,外层找到Class Chinese类字典 25 26 #实例属性没有函数属性,函数属性属于类 27 print(Chinese.__dict__) 28 Chinese.sui_di_tu_tan() 29 Chinese.cha_dui(p1) 30 31 #p1.sui_di_tu_tan() #class把p1作为参数自动加到sui_di_tu_tan(p1)括号里面,所以会报错。因为是python底层自动加上的。 32 p1.cha_dui() #p1里面没有,但是类里面有,所以能找到
执行结果:
1 我是初始化函数,我开始运行了 2 我结束啦 3 {'mingz': '元昊', 'xingbin': 'female', 'nianji': '18'} 4 元昊 5 共产堂 6 {'__init__': <function Chinese.__init__ at 0x0121F0C0>, '__doc__': '这是一个中国人的类', '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, 'sui_di_tu_tan': <function Chinese.sui_di_tu_tan at 0x0121F270>, 'dang': '共产堂', 'cha_dui': <function Chinese.cha_dui at 0x0121F228>, '__dict__': <attribute '__dict__' of 'Chinese' objects>} 7 在地上就是一口痰 8 <__main__.Chinese object at 0x01681210> 9 <__main__.Chinese object at 0x01681210> 插到了前面 10 <__main__.Chinese object at 0x01681210> 11 <__main__.Chinese object at 0x01681210> 插到了前面 12 China 13 Japan 14 {'name': 'alex'} 15 {'__init__': <function Chinese.__init__ at 0x0121F108>, 'dang': '共产堂', '__module__': '__main__', 'play_ball': <function Chinese.play_ball at 0x0121F198>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, 'country': 'Japan', '__doc__': None, '__dict__': <attribute '__dict__' of 'Chinese' objects>} 16 共产堂 17 {'__init__': <function Chinese.__init__ at 0x0121F108>, '__module__': '__main__', 'play_ball': <function Chinese.play_ball at 0x0121F198>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None, '__dict__': <attribute '__dict__' of 'Chinese' objects>} 18 {'__init__': <function Chinese.__init__ at 0x0121F108>, '__module__': '__main__', 'play_ball': <function Chinese.play_ball at 0x0121F198>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None, 'eat': <function eat_food at 0x011F2F60>, '__dict__': <attribute '__dict__' of 'Chinese' objects>} 19 alex 正在吃虾 20 test
1.4、特殊实例属性
__class__
__dict__
1 class Chinese: 2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物' 3 government='共产_党' 4 def __init__(self,name,age,gender): 5 self.name=name 6 self.age=age 7 self.gender=gender 8 9 def sui_di_tu_tan(): 10 print('90%的中国人都喜欢随地吐痰') 11 12 # def cha_dui(self): 13 # print('一个中国人-->%s<--插到了前面' %self) 14 15 def cha_dui(self): 16 print('一个中国人-->姓名:%s 年龄:%s 性别:%s<--插到了前面' %(self.name,self.age,self.gender)) 17 18 def eat_food(self,food): 19 print('%s 正在吃 %s' %(self.name,food)) 20 21 person1=Chinese('alex',1000,'female') 22 23 print(person1.__class__) 24 print(Chinese) 25 26 person2=person1.__class__('xiaobai',900,'male') 27 print(person2.name,person2.age,person2.gender)
警告:类和对象虽然调用__dict__返回的是一个字典结构,但是千万不要直接修改该字典,会导致你的oop不稳定。
1.5、类属性与对象(实例)属性
1、类属性的增、删、改、查
1 class Chinese: 2 country='China' 3 def __init__(self,name): 4 self.name=name 5 6 def play_ball(self,ball): 7 print('%s 正在打 %s' %(self.name)) 8 9 #查看 10 print(Chinese.country) 11 12 #修改 13 Chinese.country='Japan' 14 print(Chinese.country) 15 16 p1=Chinese('alex') 17 print(p1.__dict__) #从类的字典里面去找,上面已经修改过了,所以是Japan 18 19 #增加 20 Chinese.dang='共产堂' 21 22 #printChinese.dang) 23 #print(p1.dang) 24 25 #删除 26 del Chinese.dang 27 del Chinese.country 28 29 print(Chinese.__dict__) 30 #print(Chinese.country) 31 32 33 #给类增加一个函数属性 34 def eat_food(self,food): #定义了一个函数, 35 print('%s 正在吃%s' %(self.name,food)) 36 37 Chinese.eat=eat_food 38 39 print(Chinese.__dict__) 40 p1.eat('虾') #给函数属性传参数 41 42 43 #增加 44 def test(self): 45 print('test') 46 47 Chinese.play_ball=test 48 p1.play_ball() #Chinese.play_ball(p1)
执行结果:
1 China 2 3 Japan 4 5 {'name': 'alex'} 6 7 {'play_ball': <function Chinese.play_ball at 0x01558108>, '__init__': <function Chinese.__init__ at 0x01085660>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Chinese' objects>} 8 9 {'play_ball': <function Chinese.play_ball at 0x01558108>, '__init__': <function Chinese.__init__ at 0x01085660>, '__doc__': None, 'eat': <function eat_food at 0x01532F60>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Chinese' objects>} 10 11 alex 正在吃虾 12 13 test