Python之路【第五篇】:面向对象编程 面向对象编程思维导向图
http://naotu.baidu.com/file/03516c91377d6cad0ded041aa4ce4433?token=ccaba09527261666 密码: Tim
面向:过程、函数、对象
面向过程:根据业务逻辑从上到下写垒代码!
面向过程的编程弊:每次调用的时候都的重写,代码特别长,代码重用性没有,每次增加新功能所有的代码都的修改!那有什么办法解决上面出现的弊端呢?函数就出现了。
面向函数:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可!
函数解释:
函数可以理解为一个一个的功能块,你把一个大的功能拆分成一块一块的,用某项功能的时候就去调用某个功能块即可!
函数可以理解为:乐高积木,给你一块一块的,你可以用这些积木块组成你想要的任何,功能!
函数可以调用函数!主函数的作用就是把函数进行串联、调用!函数本身是不能自己执行的如果你不调用就永不执行!
面向对象:更简单的重用代码!
什么是面向对象编程呢?就是所有的代码都是通过类和对象来实现的就是面向对象编程!
创建类和对象
面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)
Java和C#来说只支持面向对象编程,而python比较灵活即支持面向对象编程也支持函数式编程
所有语言的特性都是:封装、继承、多态(多态在python中体现的不是很好)
面向对象编程是一种编程方式:通过“类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
通过两个例子来看下:
例子一:
##方式一#函数
def Bar():
print 'Bar'
def Hello(name):
print 'i am %s' %name
Bar()
Hello('tianshuai')
#方式二
# 创建类
class Foo:
def Bar(self):
print 'Bar'
def Hello(self, name):
print 'i am %s' %name
# 根据类Foo创建对象obj
obj = Foo()
obj.Bar() #执行Bar方法
obj.Hello('tianshuai') #执行Hello方法
那个简单?肯定是第一个简单为什么?不是说类的会更简单点吗?因为咱们类的东西还没有使用到!
在没学会,封装和继承的时候,方式一是简单的!
例子二:
以数据库为例:
数据库的常用操作有:增、删、改、查
增、删、改、查是不是可以写成四个方法 ?
def fetch():def modify():
def remove():
def create()
#我假设要添加一个值create函数里是不是的有:
#连接数据库 hostname,prot,username,password,dbname
#我是不是的保存这么多东西进行连接啊!连接之后是不是的打开数据库
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
那添加需吗?修改需要吗?查找需要吗?都需要那么看下实际的函数式编程的效果:
def fetch(hostname,prot,username,password,dbname ,arg ):
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
def modify(hostname,prot,username,password,dbname ,arg ):
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
def remove(hostname,prot,username,password,dbname ,arg ):
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
def create(hostname,prot,username,password,dbname ,arg)
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
每一个函数里都包含了一些字段!你都给他参数化,这些是不是都的加到参数里边,你执行的时候都的给他传参数进去!
fetch (hostname,prot,username,password,dbname ,[11,22,33,44])
modify (hostname,prot,username,password,dbname ,[11,22,33,44])
creremove ate(hostname,prot,username,password,dbname ,[11,22,33,44])
crcreate eate(hostname,prot,username,password,dbname ,[11,22,33,44])
每次操作的时候是不是都的给他写一遍!
上面的方法是通过函数来实现的,那么看下,下面的例子通过面向对象来实现:
#!/usr/bin/env python#-*- coding:utf-8 -*-
class Db_contrl(object):
def __init__(self,hostname,port,username,password,dbname): #__init__ 构造方法,在实例化的时候执行
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.dbname = dbname
def fetch(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
def modify(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
def create(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
def remove(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
obj1 = Db_contrl('1,1,1,1',80,'tianshuai','shuaige','testdb')
obj1.fetch()
obj1.modify()
obj1.create()
obj1.remove()
我现在在去调用的类里的方法的时候还需要去传参数吗?不需要了,python面向对象的最主要的就是封装!
那这些参数在那里呢?
obj1 = Db_contrl('1,1,1,1',80,'tianshuai','shuaige','testdb') 在实例化的时候我就把这些参数传给类了,他封装到了self中
如下图:
比如:boj1在调用一个create方法的时候,在obj1的这个对象里面不仅存储这个对象的参数,还有一个隐藏的参数叫做“类对象指针”,
他的作用就是告诉对象,去那里找方法!想想一下如果没有这个类对象指针,对象知道是那个模板创建的他吗?不知道的!
并且对象里是没有方法的方法是存储在类中的!如上图方法里每个都有:self 意思就是:obj1调用就是等于 def create(obj1) !!!
相比函数式编程,我是是不是每次调用的时候就没必要传一大堆参数了?
看完上面的例子就的想到:如果在一些方法里共同使用了一组变量,如果这时候使用函数式编程,每次调用方法的时候都的传这些参数!
这时候就要想到使用面向对象:把这些变量封装到对象中,每次调用的时候直接传这个对象即可!
例子三:
如果有有一个游戏,我要创建角色用函数怎么创建?是不是的写很多函数来实现很麻烦看下我的代码!
#!/usr/bin/env python#-*- coding:utf-8 -*-
'''
定义:游戏角色模板和基础功能
'''
import random
class Game_pmodel(object):
def __init__(self,name,profession,attack=0,blood=0,speed=0): #构造函数,名字和职业等信息
self.name = name #定义普通字段
self.profession = profession #定义普通字段
self.attack = attack
self.blood = blood
self.speed = speed
def supershuai(self):
self.blood = self.blood + 1000
self.attack = self.attack + 1000
self.speed = self.speed + 1000
print "\033[32;1m呼叫及时当前血量:%s 当前攻击为:%s,当前速度为:%s" % (self.blood,self.attack,self.speed)
def add_attack(self):
self.attack = self.attack +300
print "\033[32;1m您当前的攻击力为%s\033[0m" % self.attack
def aspirine(self):
self.blood = self.blood + 300
print "\033[32;1m您当前的血量为%s\033[0m" % self.blood
def detail(self):
"""注释:当前对象的详细情况"""
temp = "角色:%s ; 职业:%s ; 战斗力:%s ; 血量:%s ; 速度:%s" % (self.name, self.profession, self.attack, self.blood,self.speed)
print temp
我在创建一个角色的时候:
obj1 = Game_pmodel('角色名称','职业',攻击,'血量','速度')
那么现在看下!现在创建了一个实实在在的角色,他有自己的名字、职业、攻击、血量、速度、。如果要用函数写,会不会死!
总结:动态的创建一个东西,创建的时候的要依据某一个模板,当你在动态的创建某一类东西的时候,就的用面向对象!
继承
继承非常简单,举个例子来说,我现在有个角色的模板了,我可以根据这个角色的模板创建不通的角色,现在我有个需求,我要单独在写一个战士的模板
我上面写的那个类里的东西,很多重复的可以使用的,我是不是可以使用呢?难道我还需要重新写一遍吗?python这里提供了一个简单的方法“继承”!
之前说过python的面向对象,就是让你更好的去重用你的代码!
#!/usr/bin/env python#-*- coding:utf-8 -*-
class Game_pmodel(object):
def __init__(self,name,profession,attack=0,blood=0,speed=0): #构造函数,名字和职业等信息
self.name = name #定义普通字段
self.profession = profession #定义普通字段
self.attack = attack
self.blood = blood
self.speed = speed
def supershuai(self):
self.blood = self.blood + 1000
self.attack = self.attack + 1000
self.speed = self.speed + 1000
print "\033[32;1m呼叫及时当前血量:%s 当前攻击为:%s,当前速度为:%s" % (self.blood,self.attack,self.speed)
def add_attack(self):
self.attack = self.attack +300
print "\033[32;1m您当前的攻击力为%s\033[0m" % self.attack
def aspirine(self):
self.blood = self.blood + 300
print "\033[32;1m您当前的血量为%s\033[0m" % self.blood
def detail(self):
"""注释:当前对象的详细情况"""
temp = "角色:%s ; 职业:%s ; 战斗力:%s ; 血量:%s ; 速度:%s" % (self.name, self.profession, self.attack, self.blood,self.speed)
print temp
class Warrior(Game_pmodel):
def weapon(self):
self.attack = self.attack + 1000
print "\033[32;1m拿起武器攻击力+1000,您现在的攻击力是:%s \033[0m" % self.attack
在第二个类里面:Warrior,我并没有设置attack字段,那是那里来呢!class Warrior(Game_pmodel): 在这里继承了基类的字段和,方法!如下:
我通过战士的这个类,实例化了一个角色,但是我并在这里并没有add_attack() 那里来的呢?就是继承来的,so 这个就是继承!
在这里有个点需要提下,“经典类”、“新式类” ,还有他的多继承!(Python的类可以继承多个类,Java和C#中则只能继承一个类)
上面的截图!有(object)就是新式类,有什么区别!新式类,有些修改和新增了一些功能,以后建议使用“新式类”
这里需要提的一点是在多继承的时候的问题:
不管是直接、或间接的继承新式类,那么你的类也是新式类!
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
那么问题来了,如果在继承里有“经典类”和“新式类”谁优先呢?看下面的代码和图:
class D(object):def bar(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
pass
class A(B,C):
pass
a = A()
a.bar()
只有在上面的这种情况下是广度优先!
总结
面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用
类 是一个模板,模板中包装了多个“函数”供使用
对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数
面向对象三大特性:封装、继承和多态(多态在python体现的不是很好)
函数式编程 和 面向对象 如何选择?分别在什么情况下使用?
对于 C# 和 Java 程序员来说不存在这个问题,因为该两门语言只支持面向对象编程(不支持函数式编程)。而对于 Python 和 PHP 等语言却同时支持两种编程方式,且函数式编程能完成的操作,面向对象都可以实现;而面向对象的能完成的操作,函数式编程不行(函数式编程无法实现面向对象 的封装功能)。
所以,一般在Python开发中,全部使用面向对象 或 面向对象和函数式混合使用
更多请看:http://www.cnblogs.com/wupeiqi/p/4493506.html
http://naotu.baidu.com/file/03516c91377d6cad0ded041aa4ce4433?token=ccaba09527261666 密码: Tim
面向:过程、函数、对象
面向过程:根据业务逻辑从上到下写垒代码!
面向过程的编程弊:每次调用的时候都的重写,代码特别长,代码重用性没有,每次增加新功能所有的代码都的修改!那有什么办法解决上面出现的弊端呢?函数就出现了。
面向函数:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可!
函数解释:
函数可以理解为一个一个的功能块,你把一个大的功能拆分成一块一块的,用某项功能的时候就去调用某个功能块即可!
函数可以理解为:乐高积木,给你一块一块的,你可以用这些积木块组成你想要的任何,功能!
函数可以调用函数!主函数的作用就是把函数进行串联、调用!函数本身是不能自己执行的如果你不调用就永不执行!
面向对象:更简单的重用代码!
什么是面向对象编程呢?就是所有的代码都是通过类和对象来实现的就是面向对象编程!
创建类和对象
面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)
Java和C#来说只支持面向对象编程,而python比较灵活即支持面向对象编程也支持函数式编程
所有语言的特性都是:封装、继承、多态(多态在python中体现的不是很好)
面向对象编程是一种编程方式:通过“类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
通过两个例子来看下:
例子一:
##方式一#函数
def Bar():
print 'Bar'
def Hello(name):
print 'i am %s' %name
Bar()
Hello('tianshuai')
#方式二
# 创建类
class Foo:
def Bar(self):
print 'Bar'
def Hello(self, name):
print 'i am %s' %name
# 根据类Foo创建对象obj
obj = Foo()
obj.Bar() #执行Bar方法
obj.Hello('tianshuai') #执行Hello方法
那个简单?肯定是第一个简单为什么?不是说类的会更简单点吗?因为咱们类的东西还没有使用到!
在没学会,封装和继承的时候,方式一是简单的!
例子二:
以数据库为例:
数据库的常用操作有:增、删、改、查
增、删、改、查是不是可以写成四个方法 ?
def fetch():def modify():
def remove():
def create()
#我假设要添加一个值create函数里是不是的有:
#连接数据库 hostname,prot,username,password,dbname
#我是不是的保存这么多东西进行连接啊!连接之后是不是的打开数据库
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
那添加需吗?修改需要吗?查找需要吗?都需要那么看下实际的函数式编程的效果:
def fetch(hostname,prot,username,password,dbname ,arg ):
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
def modify(hostname,prot,username,password,dbname ,arg ):
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
def remove(hostname,prot,username,password,dbname ,arg ):
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
def create(hostname,prot,username,password,dbname ,arg)
#连接数据库 hostname,prot,username,password,dbname
#打开
#操作
#关闭
每一个函数里都包含了一些字段!你都给他参数化,这些是不是都的加到参数里边,你执行的时候都的给他传参数进去!
fetch (hostname,prot,username,password,dbname ,[11,22,33,44])
modify (hostname,prot,username,password,dbname ,[11,22,33,44])
creremove ate(hostname,prot,username,password,dbname ,[11,22,33,44])
crcreate eate(hostname,prot,username,password,dbname ,[11,22,33,44])
每次操作的时候是不是都的给他写一遍!
上面的方法是通过函数来实现的,那么看下,下面的例子通过面向对象来实现:
#!/usr/bin/env python#-*- coding:utf-8 -*-
class Db_contrl(object):
def __init__(self,hostname,port,username,password,dbname): #__init__ 构造方法,在实例化的时候执行
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.dbname = dbname
def fetch(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
def modify(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
def create(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
def remove(self):
#连接数据库self.hostname,self.port,self.username,self.password,self.dbname
#打开
#操作
#关闭
obj1 = Db_contrl('1,1,1,1',80,'tianshuai','shuaige','testdb')
obj1.fetch()
obj1.modify()
obj1.create()
obj1.remove()
我现在在去调用的类里的方法的时候还需要去传参数吗?不需要了,python面向对象的最主要的就是封装!
那这些参数在那里呢?
obj1 = Db_contrl('1,1,1,1',80,'tianshuai','shuaige','testdb') 在实例化的时候我就把这些参数传给类了,他封装到了self中
如下图:
比如:boj1在调用一个create方法的时候,在obj1的这个对象里面不仅存储这个对象的参数,还有一个隐藏的参数叫做“类对象指针”,
他的作用就是告诉对象,去那里找方法!想想一下如果没有这个类对象指针,对象知道是那个模板创建的他吗?不知道的!
并且对象里是没有方法的方法是存储在类中的!如上图方法里每个都有:self 意思就是:obj1调用就是等于 def create(obj1) !!!
相比函数式编程,我是是不是每次调用的时候就没必要传一大堆参数了?
看完上面的例子就的想到:如果在一些方法里共同使用了一组变量,如果这时候使用函数式编程,每次调用方法的时候都的传这些参数!
这时候就要想到使用面向对象:把这些变量封装到对象中,每次调用的时候直接传这个对象即可!
例子三:
如果有有一个游戏,我要创建角色用函数怎么创建?是不是的写很多函数来实现很麻烦看下我的代码!
#!/usr/bin/env python#-*- coding:utf-8 -*-
'''
定义:游戏角色模板和基础功能
'''
import random
class Game_pmodel(object):
def __init__(self,name,profession,attack=0,blood=0,speed=0): #构造函数,名字和职业等信息
self.name = name #定义普通字段
self.profession = profession #定义普通字段
self.attack = attack
self.blood = blood
self.speed = speed
def supershuai(self):
self.blood = self.blood + 1000
self.attack = self.attack + 1000
self.speed = self.speed + 1000
print "\033[32;1m呼叫及时当前血量:%s 当前攻击为:%s,当前速度为:%s" % (self.blood,self.attack,self.speed)
def add_attack(self):
self.attack = self.attack +300
print "\033[32;1m您当前的攻击力为%s\033[0m" % self.attack
def aspirine(self):
self.blood = self.blood + 300
print "\033[32;1m您当前的血量为%s\033[0m" % self.blood
def detail(self):
"""注释:当前对象的详细情况"""
temp = "角色:%s ; 职业:%s ; 战斗力:%s ; 血量:%s ; 速度:%s" % (self.name, self.profession, self.attack, self.blood,self.speed)
print temp
我在创建一个角色的时候:
obj1 = Game_pmodel('角色名称','职业',攻击,'血量','速度')
那么现在看下!现在创建了一个实实在在的角色,他有自己的名字、职业、攻击、血量、速度、。如果要用函数写,会不会死!
总结:动态的创建一个东西,创建的时候的要依据某一个模板,当你在动态的创建某一类东西的时候,就的用面向对象!
继承
继承非常简单,举个例子来说,我现在有个角色的模板了,我可以根据这个角色的模板创建不通的角色,现在我有个需求,我要单独在写一个战士的模板
我上面写的那个类里的东西,很多重复的可以使用的,我是不是可以使用呢?难道我还需要重新写一遍吗?python这里提供了一个简单的方法“继承”!
之前说过python的面向对象,就是让你更好的去重用你的代码!
#!/usr/bin/env python#-*- coding:utf-8 -*-
class Game_pmodel(object):
def __init__(self,name,profession,attack=0,blood=0,speed=0): #构造函数,名字和职业等信息
self.name = name #定义普通字段
self.profession = profession #定义普通字段
self.attack = attack
self.blood = blood
self.speed = speed
def supershuai(self):
self.blood = self.blood + 1000
self.attack = self.attack + 1000
self.speed = self.speed + 1000
print "\033[32;1m呼叫及时当前血量:%s 当前攻击为:%s,当前速度为:%s" % (self.blood,self.attack,self.speed)
def add_attack(self):
self.attack = self.attack +300
print "\033[32;1m您当前的攻击力为%s\033[0m" % self.attack
def aspirine(self):
self.blood = self.blood + 300
print "\033[32;1m您当前的血量为%s\033[0m" % self.blood
def detail(self):
"""注释:当前对象的详细情况"""
temp = "角色:%s ; 职业:%s ; 战斗力:%s ; 血量:%s ; 速度:%s" % (self.name, self.profession, self.attack, self.blood,self.speed)
print temp
class Warrior(Game_pmodel):
def weapon(self):
self.attack = self.attack + 1000
print "\033[32;1m拿起武器攻击力+1000,您现在的攻击力是:%s \033[0m" % self.attack
在第二个类里面:Warrior,我并没有设置attack字段,那是那里来呢!class Warrior(Game_pmodel): 在这里继承了基类的字段和,方法!如下:
我通过战士的这个类,实例化了一个角色,但是我并在这里并没有add_attack() 那里来的呢?就是继承来的,so 这个就是继承!
在这里有个点需要提下,“经典类”、“新式类” ,还有他的多继承!(Python的类可以继承多个类,Java和C#中则只能继承一个类)
上面的截图!有(object)就是新式类,有什么区别!新式类,有些修改和新增了一些功能,以后建议使用“新式类”
这里需要提的一点是在多继承的时候的问题:
不管是直接、或间接的继承新式类,那么你的类也是新式类!
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
那么问题来了,如果在继承里有“经典类”和“新式类”谁优先呢?看下面的代码和图:
class D(object):def bar(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
pass
class A(B,C):
pass
a = A()
a.bar()
只有在上面的这种情况下是广度优先!
总结
面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用
类 是一个模板,模板中包装了多个“函数”供使用
对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数
面向对象三大特性:封装、继承和多态(多态在python体现的不是很好)
函数式编程 和 面向对象 如何选择?分别在什么情况下使用?
对于 C# 和 Java 程序员来说不存在这个问题,因为该两门语言只支持面向对象编程(不支持函数式编程)。而对于 Python 和 PHP 等语言却同时支持两种编程方式,且函数式编程能完成的操作,面向对象都可以实现;而面向对象的能完成的操作,函数式编程不行(函数式编程无法实现面向对象 的封装功能)。
所以,一般在Python开发中,全部使用面向对象 或 面向对象和函数式混合使用
更多请看:http://www.cnblogs.com/wupeiqi/p/4493506.html
以上是 Python之路【第五篇】:面向对象编程 面向对象编程思维导向图 的全部内容, 来源链接: utcz.com/z/386667.html