编程范式

  编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式。 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路, 大多数语言只支持一种编程范式,当然也有些语言可以同时支持多种编程范式。 两种最重要的编程范式分别是面向过程编程和面向对象编程

面向过程编程

  面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。程序从上到下一步步执行,一步步从上到下,从头到尾的解决问题 。基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个小问题或子过程,这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。这样做的问题也是显而易见的,就是如果你要对程序进行修改,对你修改的那部分有依赖的各个部分你都也要跟着修改, 随着程序越来越大, 这种编程方式的维护难度会越来越高。 所以我们一般认为, 如果你只是写一些简单的脚本,去做一些一次性任务,用面向过程的方式是极好的,但如果你要处理的任务是复杂的,且需要不断迭代和维护的, 那还是用面向对象最方便了。

示例:

#面向过程编程

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 = name
self.age = age
self.gender = gender def 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 = weapon
self.life_value = life_value
self.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 = role
self.weapon = weapon
self.life_value = life_value
self.money = money r1 = 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 = role
self.weapon = weapon
self.life_value = life_value
self.money = money r1 = Role('Alex','police',"AK47") #实例
r1.name="wupeiqi"
r1.bullet= True print(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 = role
self.weapon = weapon
self.life_value = life_value
self.money = money r1 = 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 123 Role.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 = role
self.weapon = weapon
self.life_value = life_value
self.money = money r1 = 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 = role
self.weapon = weapon
self.life_value = life_value
self.money = money def __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 r1 r2.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 = name
self.role = role
self.weapon = weapon
self.__life_value = life_value #定义私有属性,私有属性在外部不能调用,只能在类里面使用
self.money = money def 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 = name
self.age = age def eat(self):
print("%s is eating..."%self.name) def sleep(self):
print("%s is sleeping...."%self.name) class Man(People): #继承类People
def play(self): #增加新功能
print("%s is playing...."%self.name) def sleep(self): #重构sleep功能
People.sleep(self)
print("man is sleeping....") class Woman(People): #继承类People
def 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 = name
self.age = age def 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 = money
print("%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 = name
self.age = age def 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):
pass class C(A):
def __init__(self):
print("C") class D(B,C):
pass obj = D()
#A #新式类 class A(object):
def __init__(self):
print("A") class B(A):
pass class C(A):
def __init__(self):
print("C") class D(B,C):
pass obj = D()
#C

当类是经典类时,多继承情况下,会按照深度优先方式查找;当类是新式类时,多继承情况下,会按照广度优先方式查找;具体参考下图

6、多态

  多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。Pyhon不直接支持多态,但可以间接实现

看完上面的话,完全懵逼; 说人话!!--》一个接口,多种实现,实现接口重用

#多态
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name @staticmethod
def 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!

  

  

Python开发【第六章】:面向对象的更多相关文章

  1. Python第六章 面向对象

    第六章 面向对象 1.面向对象初了解 ​ 面向对象的优点: ​ 1.对相似功能的函数,同一个业务下的函数进行归类,分类 ​ 2.类是一个公共的模板,对象就是从具体的模板中实例化出来的,得到对象就得到一 ...

  2. ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

    原文:ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性 深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开 ...

  3. python 教程 第六章、 模块

    第六章. 模块 1) 模块 sys模块 字节编译的.pyc文件,优化编译后生成pyo文件 2) from..import语句 import sys print 'The command line ar ...

  4. 进击的Python【第六章】:Python的高级应用(三)面向对象编程

    Python的高级应用(三)面向对象编程 本章学习要点: 面向对象编程介绍 面向对象与面向过程编程的区别 为什么要用面向对象编程思想 面向对象的相关概念 一.面向对象编程介绍 面向对象程序设计(英语: ...

  5. 那些年被我坑过的Python——玄而又玄(第六章 面向对象编程基础)

    面向对象编程: 面向对象顾名思义,就是把组织代码的粒度从函数级别抽象到对象级别,对象是通过类来生成的,类可以想象为模板或进本框架而对象是在原有模板或框架的基础上增加详细信息的实体,类,有分类.聚类的含 ...

  6. python学习笔记六 初识面向对象上(基础篇)

    python面向对象   面向对象编程(Object-Oriented Programming )介绍   对于编程语言的初学者来讲,OOP不是一个很容易理解的编程方式,虽然大家都知道OOP的三大特性 ...

  7. Python开发【第一章】:Python简介和入门

    Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...

  8. Python开发【第一章】:简介和入门

    Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...

  9. Python开发【第九章】:堡垒机实例

    一.堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块基于SSH用于连接远程服务器并执行相关操作 模块安装 C:\Program Files\Python 3.5\Scri ...

  10. Python开发【第二章】:Python模块和运算符

    一.模块初识: Python有大量的模块,从而使得开发Python程序非常简洁.类库有包括三中: Python内部提供的模块 业内开源的模块 程序员自己开发的模块 1.Python内部提供一个 sys ...

随机推荐

  1. C# 冒泡排序

    class Program { static void swap( ref int atemp, ref int btemp)//注意ref的使用 { int temp = atemp; atemp ...

  2. JS高程3:DOM-DOM操作技术

    动态脚本 加载外部脚本 方式一,直接写代码: var script = document.createElement("script"); script.type = " ...

  3. Linux下出现Read-only file system的解决办法

    正常运行中的网站,忽然间出现session目录不可写,连接服务器一看,任何关于写硬盘的命令都不能用,提示Read-only file system,使用一条命令即可搞定此问题: mount -o re ...

  4. CCNA2.0笔记_OSPF v2

    OSPF(开放最短路径优先)协议概述: - 链路状态路由协议 - 无类路由协议 - 要点:RouterID.区域ID - 触发更新 .以传播 LSA 代替路由表更新 - 快速响应变更(比距离矢量路由协 ...

  5. jdbc preparedstatement 调用存储过程的问题

    preparedstatement   是可以执行正常的存储过程 executeQuery() 正常执行 在实际开发中遇到一种问题当 preparedstatement.setMaxRows 设置了这 ...

  6. iOS swift HandyJSON组合Alamofire发起网络请求并转换成模型

    在swift开发中,发起网络请求大部分开发者应该都是使用Alamofire发起的网络请求,至于请求完成后JSON解析这一块有很多解决方案,我们今天这里使用HandyJSON来解析请求返回的数据并转化成 ...

  7. C# 时间格式 yyyy/mm/dd

    今天遇到个问题在C#中将日期格式设置为yyyy/MM/dd,我是这样写的: DateTime.Now.ToString("yyyy/MM/dd"); 可是获取到的日期还是显示yyy ...

  8. 新版期货数据交换(FTD)协议报文分析

    因为需要开发模拟CTP后台服务,实现一键切换CTP,所以我们需要分析CTP报文.(基于FTD协议2004版改进)   网上公开的只能找到04年老版本,和现前报文格式出入较大.参考:http://www ...

  9. javascript不同类型数据之间的运算是如何转换的

    js中不同类型的基础数据之间可以转换,这种转换是有规则可寻的,并非随意的随机的.在js中有5种基础类型数据:string.number.boolean.null.undefined,其中,常用于计算或 ...

  10. [Win10应用开发] 如何使用Windows通知

    消息通知,是一个应用中必不可少的组成部分.Win10下提供了多种消息通知机制,Toast通知只是其中一种.这篇博文和大家分享一下,如何使用Toast通知. 上图是一个基本的Toast通知,那我们该如何 ...