Python开发【第六章】:面向对象
编程范式
编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式。 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路, 大多数语言只支持一种编程范式,当然也有些语言可以同时支持多种编程范式。 两种最重要的编程范式分别是面向过程编程和面向对象编程
面向过程编程
面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。程序从上到下一步步执行,一步步从上到下,从头到尾的解决问题 。基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个小问题或子过程,这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。这样做的问题也是显而易见的,就是如果你要对程序进行修改,对你修改的那部分有依赖的各个部分你都也要跟着修改, 随着程序越来越大, 这种编程方式的维护难度会越来越高。 所以我们一般认为, 如果你只是写一些简单的脚本,去做一些一次性任务,用面向过程的方式是极好的,但如果你要处理的任务是复杂的,且需要不断迭代和维护的, 那还是用面向对象最方便了。
示例:
#面向过程编程while True:if cpu利用率 > 90%:#发送邮件提醒连接邮箱服务器发送邮件关闭连接if 硬盘使用空间 > 90%:#发送邮件提醒连接邮箱服务器发送邮件关闭连接if 内存占用 > 80%:#发送邮件提醒连接邮箱服务器发送邮件关闭连接
函数式编程
将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
示例:
练习:在终端输出如下信息小明,10岁,男,上山去砍柴 小明,10岁,男,开车去东北 小明,10岁,男,最爱大保健 老李,90岁,男,上山去砍柴 老李,90岁,男,开车去东北 老李,90岁,男,最爱大保健
练习一
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-Lian#函数式编程def firewood(name, age, gender):print("%s,%s岁,%s,上山去砍柴" %(name, age, gender))def drive(name, age, gender):print("%s,%s岁,%s,开车去东北" %(name, age, gender))def dbj(name, age, gender):print("%s,%s岁,%s,最爱大保健" %(name, age, gender))firewood('小明', 10, '男')
drive('小明', 10, '男')
dbj('小明', 10, '男')
#小明,10岁,男,上山去砍柴
#小明,10岁,男,开车去东北
#小明,10岁,男,最爱大保健firewood('老李', 90, '男')
drive('老李', 90, '男')
dbj('老李', 90, '男')
#老李,90岁,男,上山去砍柴
#老李,90岁,男,开车去东北
#老李,90岁,男,最爱大保健
面向对象编程
1、类、对象、实例
OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。
示例:
练习:在终端输出如下信息小明,10岁,男,上山去砍柴 小明,10岁,男,开车去东北 小明,10岁,男,最爱大保健 老李,90岁,男,上山去砍柴 老李,90岁,男,开车去东北 老李,90岁,男,最爱大保健
练习一
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-Lian#面向对象
class Foo:def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = genderdef firewood(self):print("%s,%s岁,%s,上山去砍柴" % (self.name, self.age, self.gender))def drive(self):print("%s,%s岁,%s,开车去东北" % (self.name, self.age, self.gender))def dbj(self):print("%s,%s岁,%s,最爱大保健" % (self.name, self.age, self.gender))xiaoming = Foo('小明', 10, '男')
xiaoming.firewood()
xiaoming.drive()
xiaoming.dbj()
#小明,10岁,男,上山去砍柴
#小明,10岁,男,开车去东北
#小明,10岁,男,最爱大保健laoli = Foo('老李', 90, '男')
laoli.firewood()
laoli.drive()
laoli.dbj()
#老李,90岁,男,上山去砍柴
#老李,90岁,男,开车去东北
#老李,90岁,男,最爱大保健
面向对象编程的主要作用也是使你的代码修改和扩展变的更容易,那么小白要问了,既然函数都能实现这个需求了,还要OOP干毛线用呢? 呵呵,说这话就像,古时候,人们打仗杀人都用刀,后来出来了枪,它的主要功能跟刀一样,也是杀人,然后小白就问,既然刀能杀人了,那还要枪干毛线,哈哈,显而易见,因为枪能更好更快更容易的杀人。函数编程与OOP的主要区别就是OOP可以使程序更加容易扩展和易更改。
上面的程序做个简单认识即可,下面我们通过写一个cs程序来对面向对象编程做进一步认识
CS游戏 1、暂不考虑开发场地等复杂的东西,角色恐怖份子、警察 2、每个人都有生命值 3、武器 4、被打中后就会掉血的功能 5、开枪功能 6、换子弹 7、买枪
CS游戏
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-Lian#面向对象class
class Role(object): #定义一个类, class是定义类的语法,Role是类名,(object)是新式类的写法,暂且先记住def __init__(self,name,role,weapon,life_value=100,money=15000):#初始化函数,在生成一个角色时要初始化的一些属性就填写在这里self.name = name #__init__中的第一个参数self为实例名称self.role = role self.weapon = weaponself.life_value = life_valueself.money = money#__init__()叫做初始化方法(或构造方法), 在类被调用时,这个方法(虽然它是函数形式,但在类中就不叫函数了, 叫方法)会自动执行,# 进行一些初始化的动作def shot(self):# 开了枪后要减子弹数print("%s is shooting......."%(self.name))def got_shot(self):# 中枪后要减血print("ah.....%s:I got shot...."%(self.name))def buy_gun(self,gun_name):# 检查钱够不够,买了枪后要扣钱print("%s just bought %s "%(self.name,gun_name))#生成一个角色 , 会自动把参数传给Role下面的__init__(...)方法,这个过程叫做类的实例化,r1叫做类的实例
r1 = Role('Alex','police',"AK47") #此时self 相当于 r1 , Role(r1,'Alex','police','AK47’)
r2 = Role('Jack','terrorist',"B22") #此时self 相当于 r2 , Role(r2,'Jack','terrorist','B22’)print(r1,type(r1))
print(r1.role)
r1.shot()
r1.got_shot()
r1.buy_gun("DZT100")
# <__main__.Role object at 0x005A5BF0> <class '__main__.Role'>
# police
# Alex is shooting.......
# ah.....Alex:I got shot....
# Alex just bought DZT100
2、类变量和实例变量
类变量为大家都共有的变量,只加载在类内存当中,不会加载在每个实例里;举个栗子:创建14亿用户,大家国籍都是中国,如果不把国籍写到类变量中,而是写到实例变量默认参数中,则14亿个实例,每个都要加载国籍到内存当中,会占用大量内存,这就是为什么我们要了解类变量的意义
#类变量和实例变量
class Role(object): #定义一个类, class是定义类的语法n = 123 #类变量name = "类name"def __init__(self,name,role,weapon,life_value=100,money=15000):self.name = name #实例变量self.role = roleself.weapon = weaponself.life_value = life_valueself.money = moneyr1 = Role('Alex','police',"AK47") #实例print(Role.n,r1.n)
print(Role.name,r1.name)
#123 123
#类name Alex
由上面程序可知,类变量对全局生效,输入类名可直接调用;当类变量与实例变量相同且同时存在的话,实例变量优先
#实例变量
class Role(object): #定义一个类, class是定义类的语法n = 123 #类变量name = "类name"def __init__(self,name,role,weapon,life_value=100,money=15000):self.name = name #实例变量self.role = roleself.weapon = weaponself.life_value = life_valueself.money = moneyr1 = Role('Alex','police',"AK47") #实例
r1.name="wupeiqi"
r1.bullet= Trueprint(r1.name,r1.bullet)
#wupeiqi True
类进行实例化之后,还可以对实例变量重新赋值、增加变量
#类变量和实例变量
class Role(object): #定义一个类, class是定义类的语法n = 123 #类变量name = "类name"def __init__(self,name,role,weapon,life_value=100,money=15000):self.name = name #实例变量self.role = roleself.weapon = weaponself.life_value = life_valueself.money = moneyr1 = Role('Alex','police',"AK47") #实例
r2 = Role('lzl','terrorist','B22')r1.n = "r1的123"
print(r1.name,r1.n)
print(r2.name,r2.n)
# Alex r1的123
# lzl 123Role.n = "Role的123"
print(r1.name,r1.n)
print(r2.name,r2.n)
# Alex r1的123
# lzl Role的123
执行上面的程序发现,赋值r1.n后只是影响到实例r1,对r2.n并没有任何影响,这是因为赋值的实例变量与类变量名一样时,并不会改变类变量中的值,只影响到当前实例;当重新赋值类变量时,r2也跟着改变;哈哈,此时你以为你都懂了,那让我们对上面的程序做个升级吧!!
#类变量和实例变量
class Role(object): #定义一个类, class是定义类的语法list = [] #定义一个列表类变量def __init__(self,name,role,weapon,life_value=100,money=15000):self.name = name #实例变量self.role = roleself.weapon = weaponself.life_value = life_valueself.money = moneyr1 = Role('Alex','police',"AK47") #实例
r2 = Role('lzl','terrorist','B22')print(Role.list) #此时list为空
#[]r1.list.append("from r1")
r2.list.append("from r2")print(r1.list)
print(r2.list)
#['from r1', 'from r2']
# ['from r1', 'from r2']print(Role.list)
# ['from r1', 'from r2']
从上面的程序可看出r1、r2改变了类变量;懒得解释了,自己理解吧O(∩_∩)O哈哈~
3、析构函数
在实例释放、销毁的时候执行,通常用于做一下收尾工作(如关闭数据连接)
#析构函数
class Role(object): #定义一个类, class是定义类的语法def __init__(self,name,role,weapon,life_value=100,money=15000):self.name = name #实例变量self.role = roleself.weapon = weaponself.life_value = life_valueself.money = moneydef __del__(self):print("%s 彻底死了"%self.name)def shot(self):# 开了枪后要减子弹数print("%s is shooting......."%(self.name))def got_shot(self):# 中枪后要减血print("ah.....%s:I got shot...."%(self.name))r1 = Role('Alex','police',"AK47")
r2 = Role('Wupeiqi','terrorist','B22')r1.got_shot()
del r1r2.got_shot()# ah.....Alex:I got shot....
# Alex 彻底死了
# ah.....Wupeiqi:I got shot....
# Wupeiqi 彻底死了
程序结束、del删除实例时才会执行__del__里的内容
4、私有属性、私有方法
记住私有的概念:只能在类里面进行调用 看完下面的代码你就明白了
#class私有属性、私有方法
class Role(object): #定义一个类, class是定义类的语法def __init__(self,name,role,weapon,life_value=100,money=15000):self.name = nameself.role = roleself.weapon = weaponself.__life_value = life_value #定义私有属性,私有属性在外部不能调用,只能在类里面使用self.money = moneydef show_status(self): #定义函数,调用私有属性print("name:%s weapon:%s life_value:%s"%(self.name,self.weapon,self.__life_value))def __shot(self): #定义私有方法print("%s is shooting......."%(self.name))def got_shot(self):self.__shot() #调用私有方法print("ah.....%s:I got shot...."%(self.name))r1 = Role('lzl','police',"AK47")#私有属性
#print(r1.__life_value) #外部调用life_vaule 直接报错
#AttributeError: 'Role' object has no attribute '__life_value'
r1.show_status() #通过方法执行私有属性
#name:lzl weapon:AK47 life_value:100#私有方法
#r1.__shot() #外部调用私有方法 直接报错
#AttributeError: 'Role' object has no attribute '__shot'
r1.got_shot() #通过其他方法执行私有方法
# lzl is shooting.......
# ah.....lzl:I got shot....
5、继承
继承:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展
#类的继承class People():def __init__(self,name,age):self.name = nameself.age = agedef eat(self):print("%s is eating..."%self.name)def sleep(self):print("%s is sleeping...."%self.name)class Man(People): #继承类Peopledef play(self): #增加新功能print("%s is playing...."%self.name)def sleep(self): #重构sleep功能People.sleep(self)print("man is sleeping....")class Woman(People): #继承类Peopledef get_birth(self): #增加新功能print("%s is born a boby...."%self.name)m1 = Man("lianzhilie",22)
w1 = Woman("Alex",33)m1.eat() #调用People方法
m1.play() #调用Man方法
# lianzhilie is eating...
# lianzhilie is playing....m1.sleep()
# lianzhilie is sleeping....
# man is sleeping...w1.get_birth()
# Alex is born a boby...
由上面程序可知,类的继承可省大量重复的代码
#类的继承,子类初始化class People():def __init__(self,name,age):self.name = nameself.age = agedef eat(self):print("%s is eating..."%self.name)def sleep(self):print("%s is sleeping...."%self.name)class Man(People):def __init__(self,name,age,money): #重构初始化 覆盖父类# People.__init__(self,name,age) #加载父类初始化super(Man,self).__init__(name,age) #加载父类初始化self.money = moneyprint("%s 一出生就有 $%s"%(self.name,self.money))def play(self): #增加新功能print("%s is playing...."%self.name)class Woman(People):def get_birth(self):print("%s is born a boby...."%self.name)m1 = Man("lianzhilie",22,1000)
w1 = Woman("Alex",33)
#lianzhilie 一出生就有 $1000
子类需要重构初始化时,会把父类的初始化覆盖掉,所以在重构时需要加载父类初始化
# 类的继承-多继承class People(object): #新式类def __init__(self, name, age):self.name = nameself.age = agedef eat(self):print("%s is eating..." % self.name)def sleep(self):print("%s is sleeping...." % self.name)class Relation(object):def make_friends(self,obj):print("%s is making friends with %s"%(self.name,obj.name))class Man(Relation,People): #多继承def play(self):print("%s is playing...." % self.name)class Woman(People):def get_birth(self):print("%s is born a boby...." % self.name)m1 = Man("lianzhilie", 22)
w1 = Woman("Alex", 33)m1.make_friends(w1)
#lianzhilie is making friends with Alex
多继承时需注意,在多继承中从父类继承初始化属性时,顺序从左到右开始初始化,只要初始化到属性数据就不再向后继续,所以越往前越优先;当父类有初始化,子类也有初始化时,执行子类的初始化,父类的不生效
刚才我们已经知道了新式类的概念,那么经典类与新式类的区别是什么呢?!
通过上面的程序我们知道Python的类可以继承多个类,那如果Python的类如果继承了多个类,有多层继承关系,那么其初始化时寻找的路线是什么样的呢?,通过下面这段代码来看下:Python3以后都是新式类了
#经典类class A():def __init__(self):print("A")
class B(A):passclass C(A):def __init__(self):print("C")class D(B,C):passobj = D()
#A#新式类class A(object):def __init__(self):print("A")class B(A):passclass C(A):def __init__(self):print("C")class D(B,C):passobj = D()
#C
当类是经典类时,多继承情况下,会按照深度优先方式查找;当类是新式类时,多继承情况下,会按照广度优先方式查找;具体参考下图
6、多态
看完上面的话,完全懵逼; 说人话!!--》一个接口,多种实现,实现接口重用
#多态
class Animal:def __init__(self, name): # Constructor of the classself.name = name@staticmethoddef animal_talk(obj):obj.talk()class Cat(Animal):def talk(self):print('%s:Meow!'%(self.name))class Dog(Animal):def talk(self):print('%s:Woof! Woof!'%(self.name))c = Cat('Missy')
d = Dog('Lassie')Animal.animal_talk(c)
Animal.animal_talk(d)# Missy:Meow!
# Lassie:Woof! Woof!
转载于:https://www.cnblogs.com/lianzhilei/p/5813986.html
Python开发【第六章】:面向对象相关推荐
- Python 第二十六章 面向对象 元类+反射+双下方法
元类 class A:pass obj = A() print(type('abc')) print(type([1,2,3])) print(type((22,33)))# type 获取对象从属于 ...
- 《编程机制探析》第六章 面向对象
<编程机制探析>第六章 面向对象 面向对象(Object Oriented)是命令式编程的主流编程模型,其概念极其重要.可以说,命令式编程几乎就是面向对象的天下. 面向对象(Object ...
- 【JAVA SE】第六章 面向对象、对象和类以及封装
第六章 面向对象.对象和类以及封装 文章目录 第六章 面向对象.对象和类以及封装 一.面向对象 1.概念 2.面向对象的三大特征 二.对象和类 1.基本概念 2.Java中的对象 3.Java 中的类 ...
- Java基础学习——第六章 面向对象编程(下)
Java基础学习--第六章 面向对象编程(下) 一.关键词:static 1. static关键字的引入 当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new ...
- ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性
深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第 ...
- 《Head First Python》第六章--定制数据对象
先上数据集:Head First Python 数据集 第六章的数据在第五章的基础上加了两个属性:姓名和出生日期 james2.txt James Lee,2002-3-14,2-34,3:21,2. ...
- Python之第六章 内置容器 --- 字典(映射)
目录 Python之第六章 内置容器 --- 字典(映射) 1.定义: 2.格式: 3.字典创建示例 4.增加字典元素 5.删除字典 6.字典的访问 7.字典的复制 8.使用get()方法获取指定的 ...
- 《疯狂Java讲义》学习笔记 第六章 面向对象(下)
<疯狂Java讲义>学习笔记 第六章 面向对象(下) 6.1包装类 基本数据类型 包装类 byte Byte short Short int Integer long Long char ...
- Python之第六章 内置容器 --- 字符串
目录 Python之第六章 内置容器 --- 字符串 1.概念 2.凭借字符串 --- + 3.多行字符串 4.字符串的切片 例 输入员工省份证号,输出出生日期 5.分隔合并字符串 分隔字符串 合并字 ...
- 路飞学城python电子书_路飞学城-Python开发集训-第一章
路飞学城-Python开发集训-第一章 1.本章学习心得.体会 我: 间接性勤奋. 我: 学习方法论:输入--输出---纠正 我: 对对对 走出舒适区, 换圈子, 转思路,投资自我加筹码. 我: 圈子 ...
最新文章
- JVM堆 栈 方法区详解
- 一个JS对话框,可以显示其它页面,
- 使用DOM4J读和写文档
- 电脑卡顿不流畅怎么解决_电脑卡顿是什么原因,电脑卡顿严重解决方法【详解】...
- 小学计算机几年级学3d建模,学了4年手绘和建模,你终于不会思考了
- sql编写将时间转换年月日 时分格式
- 活久见!月薪30k的小程序全栈开发到底有多难?
- java犯的小错误_[Java教程]十个JavaScript中易犯的小错误,你中了几枪?
- hdu3339 In Action(Dijkstra+01背包)
- crt中 新建的连接存储在哪_数字存储示波器的VPO技术
- linux top 上次更新到现在的cpu时间占用百分比,使用top命令分析linux系统性能的详解...
- 【jvm】jvisualvm 离线下载安装插件
- ASP基础教程:ASP脚本变量、函数、过程和条件语句
- 将先前的提交分成多个提交
- 23种设计模式(二十四)领域规则之解析器
- LeetCode之 x 的平方根
- 怎样裁剪照片大小尺寸?如何在线编辑图片?
- multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
- css span img,css设置span和img垂直居中(设置line-height失效)
- Sqlite数据库锁死问题
热门文章
- 用U盘制作PE启动盘
- 新出炉的 100+ 篇技术热文,在微信热传,别错过哦
- Ford-Fulkerson 标号法求网络最大流
- 安装python的时候遇到的问题,无法安装bz2modules等
- javaSE探赜索隐之三<类与对象的爱恨情仇上>
- 如何通过命令将可执行程序转入deamon(之start-stop-daemon )
- mysql1598_mysql中主从复制中出现ERROR 1598 (HY000)错误
- 大厂程序员必备的一套浏览器书签,我帮你整理好了。[下载导入浏览器]
- VCollab—大数据轻量化、可视化工具
- android获取网页标题,android获取系统自带浏览器书签