编程范式

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

面向过程编程

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

示例:

#面向过程编程

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. PHP系统学习1

    1.php变量 2.php引用变量 $name1=&$name2; 3.全局变量 4.魔术变量__LINE__,__FILE__,__FUNCTION__,__CLASS__,__METHOD ...

  2. CvSplit

    /* possible split in the tree */ typedef struct CvSplit { CvTreeCascadeNode* parent; CvTreeCascadeNo ...

  3. iOS开发多线程篇 03 —线程安全

    iOS开发多线程篇—线程安全 一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块 ...

  4. 小案例:struts1.3利用nested标签使用POJO

    其中的关键就是这个POJO是你自己去new一个,struts是不会帮你创建的!参考http://luohua.iteye.com/blog/39976 表单页 <%@ page language ...

  5. c# 遇到的问题,求解?

    c# cannot evaluate expression because the code of the current method is optimized.

  6. MVVM 实战之计算器

    MVVM 实战之计算器 android DataBinding MVVM calculator Model View 布局文件 Fragment ViewModel 结束语 前些日子,一直在学习基于 ...

  7. Oracle常用命令大全

    一.ORACLE的启动和关闭 1.在单机环境下 要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下 su - oracle a.启动ORACLE系统 oracle>svrmgrl ...

  8. python笔记9 : 多线程

    基础: 什么是进程(process)? 每一个程序的内存是独立的,例如:world不能访问QQ. 进程:QQ是以一个整体的形式暴露给操作系统管理,里面包含了各种资源的调用(内存管理.网络接口调用等). ...

  9. Codeforces 193A. Cutting Figure

    看起来非常神,但仅仅有三种情况 -1 , 1 ,2..... A. Cutting Figure time limit per test 2 seconds memory limit per test ...

  10. 【ARDUINO】串口无法打开问题

    1.查看是否串口被锁 sudo arduino ls /var/lock sudo rm /var/lock/LCK..ttyACM* 2.查看arduino安装位置 dpkg -S XXXX 3.原 ...