面向对象编程OOP

python类

  • 继承:继承顶层类的通用属性,并且在通用情况下实现一次,目的是提高代码重用性
  • 组合:由多个组件对象组合而成,通过多个对象来协作完成相应指令,每个组件都可以写成类来定义自己的属性和行为
  • 与模块的区别:内存中模块只有一个实例,只能通过重载以获取其最新的代码,而类有多个实例

python类具体特征

  • 多重实例

    • 类是产生对象实例的工厂
    • 每调用一次类,便会产生独立命名空间的新对象
    • 每个对象存储的数据是不一样
  • 通过继承进行定制
    • 在类的外部重新定义其属性
    • 建立命名空间的层次结构来定义类创建的对象所使用的变量名称
  • 运算符重载
    • 根据提供特定的协议方法,可以定义对象来响应在内置类型上的几种运算

python多重实例

  • s1:定义类模板和创建实例对象
## person.py
## 定义类模板
class Person:## python函数中在默认第一个有参数之后的任何参数都必须拥有默认值def __init__(self,name,job=None,pay=0):self.name = nameself.job = jobself.pay = paydef __str__(self):return "the name[%s] - the job[%s] - the pay[%d]" % (self.name,self.job,self.pay)## 创建实例并测试
tom = Person("tom")
jack = Person("jack",job="market",pay=20)
print(tom)
print(jack)>>> python person.py
the name[tom] - the job[None] - the pay[0]
the name[jack] - the job[market] - the pay[20]## 小结:
1)创建实例的时候使用了默认值参数以及关键字参数
2)tom和jack从技术的角度而言是属于不同的对象命名空间,都拥有类创建的独立副本
3)不足在要导入其他的python文件也会把print的信息也输出## 更改存放测试代码的位置,在文件底部添加如下代码
if __name__ == '__main__':tom = Person("tom")jack = Person("jack",job="market",pay=20)print(toml)print(jackl)>>> python person.py
the name[toml] - the job[None] - the pay[0]
the name[jackl] - the job[market] - the pay[20]>>> import person
## 没有任何输出复制代码
  • s2:添加行为方法
## python OOP编程也应当遵循封装的特性,即细节隐藏,外部访问方法## 非OOP的方式获取last name
print(jack.name.split()[-1])## OOP的准则为添加方法
class Person:....def getLastName(self):return self.name.split()[-1]## 外部调用
print(jack.getLastName()复制代码
  • s3:运算符重载
## 上述测试实例对象每次都需要去调用相应的属性名称打印显示出来,重写__str__方法来显示一个对象属性的信息
class Person:...def __str__(self):list = []for k,v in self.__dict__.items():       ## 通过动态获取实例对象的属性信息,而不是直接将属性名以及值直接硬编码list.append("%s -- %s" % (k,v))str =  ",".join(list)return "Person[%s]" % str## 上述打印出所有的对象属性信息出来
>>> print(tom)
Person[pay -- 0,name -- tom,job -- None]复制代码
  • s4:通过子类定制行为
## 扩展父类的方法,而不是去重写或者修改父类方法
class Person:....def giveRaise(self,percent):self.pay = self.pay * (1 + percent)class Manager(Person):def giveRaise(self,percent,bouns=.10):## 调用类的方法并传递self参数,这里不能用self,self本身指当前类实例对象本身,会导致循环引用而内存耗尽Person.giveRaise(self,percent + bouns)      ## 对于python调用父类方法,一般是通过类.方法(self,parameters)来显示调用,像其他编程语言,如java调用父类是通过super.方法来显示调用,这是区别## 多态
p1 = Person("p1",job="dev",pay=11000)
p2 = Manager("p2",job="dev",pay=11000)
>>> print(p1.giveRaise(.10))
>>> print(p2.giveRaise(.10))
Person[name -- p1,job -- dev,pay -- 12100.000000000002]
Person[name -- p2,job -- dev,pay -- 13200.0]## 小结:
1)python的多态和其他编程语言略有差异,只要方法名称一样便会覆盖顶层类相应的方法,不管参数个数还是参数类型
2)原因在于python的属性以及行为是根据搜索树来遍历获取最近的属性或者方法
3)python参数类型是在赋值的时候才知道的,没有预先定义的类型复制代码
  • s5:定制构造函数
## 定制Manager类,使其特殊化
class Manager(Person):def __init__(self,name,pay = 0):Person.__init__(self,name,job = "manager",pay = pay)>>> tom = Manager("tomk",pay=11000)
>>> print(tom)
Person[pay -- 13200.0,name -- tomk,job -- manager]复制代码
  • s6:使用内省工具(类似其他编程语言的"反射")

    • 问题描述1:Manager打印显示的信息是Person,然后实际中应当是显示Manager的信息
    • 问题描述2:Manager如果在init增加属性,如果是硬编码的话则通过打印出来的信息就无法显示新的属性信息
## 问题1的解决方案:
实例对象到创建它的类的链接通过instance.__class__属性
反过来,可以通过一个__name__或者是__bases__序列提供超类的访问    p1 = Person("p1",job="dev",pay=11000)
p2 = Manager("p2",pay=11000)
>>> print(p1.__class__.__name__)
Person
>>> print(p1.__class__.__bases__)
(<class 'object'>,)>>> print(p2.__class__.__name__)
Manager
>>> print(p2.__class__.__bases__)
(<class '__main__.Person'>,)## 问题2的解决方案:
通过内置的object.__dict__字典来显示实例对象的所有属性信息## 在上述person已经使用__dict__属性来显示实例属性信息
>>> print(p1)
Person[job -- dev,name -- p1,pay -- 11000]## 新增加对象属性
p1.age = 10
p1.hobby = "maths"
>>> print(p1)
Person[pay -- 11000,hobby -- maths,age -- 10,job -- dev,name -- p1]## 将上述Person改造成通用的工具显示
class Person:def get_all_attrs(self):attrs = []for key,value in self.__dict__.items():attrs.append("%s==%s" % (key,value))return ",".join(attrs)def __str__(self):return "%s[%s]" % (self.__class__.__name__,self.get_all_attrs())>>> print(p1)
Person[hobby==maths,name==p1,job==dev,pay==11000,age==10]
>>> print(p2)
Manager[name==p2,pay==11000,job==manager]## 显示类和实例对象的所有属性使用dir方法
>>> dir(p2)
## 过长没有copy复制代码
  • s7:对象持久化

    • pickle:任意python对象和字节串之间的序列化
    • dbm:实现一个可通过键访问的文件系统,以存储字符串
    • shelve:使用上述两个模块把python对象存储到一个文件中,即按键存储pickle处理后的对象并存储在dbm的文件中
## pickle## 将对象序列化到文件f1 = open("pickle.db","wb+")pickle.dump(p1,f1)  ## 这里不能一步到位,即open("pickle.db","wb+"),会导致pickle在读取的时候抛出EOFError: Ran out of input f1.close()

## 将对象序列化为字符串string = pickle.dumps(p1)

## 从文件读取f = open("pickle.db","rb")p = pickle.load(f)

## 从字符串读取p_obj = pickle.loads(string)

## dbm## 存储db = dbm.open("dbm","c")db[k1] = v1db.close()

## 读取db = dbm.open("dbm","c")for key in db.keys():    print("key[%s] -- %s" % (key,db[key]))

## shelveimport shelvedb = shelve.open("persondb")    ## filenamefor object in [p1,p2]:    db[object.name] = objectdb.close()  ## 必须关闭

## 从db文件中读取db = shelve.open("persondb")        ## db拥有和字典相同的方法,区别在于shelve需要打开和关闭操作for key in db.keys():    print("from db[%s]" % db[key])复制代码

python重载运算符

  • 双下划线命名的方法(__X__)是特殊的钩子
  • 当实例出现在内置运算时,这类方法会自动调用
  • 类可覆盖多数内置类型的运算
  • 运算符覆盖方法没有默认,而且也不需要
  • 运算符可以让类与Python的对象模型项集成
## 重载类的内置方法,一般是应用于数学类对象的计算才需要重载运算符
class OverrideClass(ClassObject):def __init__(self,data):self.data = datadef __add__(self, other):return OverrideClass(self.data + other)def __str__(self):return "[OverrideClass.data[%s]]" % self.datadef mul(self,other):self.data *= other## 调用
t = OverrideClass("9090")     ## 调用__init__方法
t2 = t+"234"                  ## 调用__add__方法,这个产生了新的对象
print t2                      ## 调用__str__方法t2.mul(3)
print(t2.data)复制代码

python属性继承搜索,object.attribute

  • 找出attribute首次出现的实例对象
  • 然后是该对象之上的所有类带有__init__方法中定义的属性查找attribute,由下至上,由左至右,属于继承搜索树
  • 最后是定义该对象的类属性,查找方式也是由下至上,由左至右的遍历搜索

编写类树

  • 每个class语句生成一个新的类对象
  • 每次类调用,就会生成一个新的实例对象
  • 实例对象自动连接到创建该实例对象的类
  • 类连接至超类的方式,将超类列在类的头部括号中,其从左至右的顺序会决定树中的次序
class M1:def __init__(self):     ## 相当于构造器self.name = "m1 name"print("M1 class")class M2:def __init__(self):self.name = "m2 name"print("M2 class")class M3(M1,M2):passclass M4(M2,M1):pass#搜索树:M3 M1 M2,在多重继承中,以括号从左到右的次序会决定超类搜索的顺序
>>> a = M3()
>>> print(a.name)
M1 class
m1 name#搜索树:M4 M2 M1
>>> b = M4()
>>> print(b.name)
M2 class
m2 name## a.name属性的查找
1.先查找当前实例对象的属性,定义对象属性是在一个特殊方法__init__定义,
1.1因此会从M3 -> M1 -> M2的搜索树中查找最近定义的__init__方法
1.2 如果__init__方法中有定义属性name则返回,否则进行下一步查找
2.如果在对象属性中没有找到,则会从类的搜索树中查找属性值,即M3 -> M1 -> M2中查找
2.1若找不到则抛出异常复制代码

python OOP总结

  • 实例创建 -- 填充实例的属性
  • 行为方法 -- 在类方法中封装逻辑
  • 运算符重载 -- 为外部调用的程序提供自身内置方法的定制化行为
  • 定制行为 -- 重新定义子类方法以使其特殊化
  • 定制构造函数 -- 为子类添加构造逻辑特殊化

喜欢可以关注我个人公众号,持续分享工程师技术日常

python面向对象编程(1)相关推荐

  1. 这可能是Python面向对象编程的最佳实践

    作者 | 崔庆才 来源 | 进击的Coder(ID:FightingCoder) Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了 ...

  2. Python面向对象编程:类继承和其衍生术语

    Python面向对象编程03:类继承和其衍生术语 前面我们讲到过正则表达式字符等,上一篇分享了面向对象编程和类的结构,最后稍微提到了继承. Python面向对象编程:深度认识类class_ Pytho ...

  3. 《Python面向对象编程指南》——1.2 基类中的__init__()方法

    本节书摘来自异步社区<Python面向对象编程指南>一书中的第1章,第1.2节,作者[美]Steven F. Lott, 张心韬 兰亮 译,更多章节内容可以访问云栖社区"异步社区 ...

  4. 关于python面向对象编程中、下列说法中_关于Python面向对象编程的知识点总结

    前言 如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程. 接下来我们 ...

  5. python对象编程例子-这是我见过最详细的Python面向对象编程!建议收藏!

    原标题:这是我见过最详细的Python面向对象编程!建议收藏! 面向对象编程和函数式编程(面向过程编程)都是程序设计的方法,不过稍有区别. 面向过程编程: 1. 导入各种外部库 2. 设计各种全局变量 ...

  6. python面向对象编程的优点-Python面向对象编程——总结面向对象的优点

    Python面向对象编程--总结面向对象的优点 一.从代码级别看面向对象 1.在没有学习类这个概念时,数据与功能是分离的 def exc1(host,port,db,charset): conn=co ...

  7. python编程基础是什么-Python面向对象编程基础解析(一)

    1.什么是面向对象 面向对象(oop)是一种抽象的方法来理解这个世界,世间万物都可以抽象成一个对象,一切事物都是由对象构成的.应用在编程中,是一种开发程序的方法,它将对象作为程序的基本单元. 2.面向 ...

  8. 【Python基础】Python 面向对象编程(上篇)

    我的施工计划图 已完成专题包括: 1我的施工计划 2数字专题 3字符串专题 4列表专题 5流程控制专题 6编程风格专题 7函数使用专题 今天是面向对象编程的上篇:基础专题 Python 面向对象编程 ...

  9. Python 面向对象编程基础

    Python面向对象编程 简介:面向对象编程--Object Oriented Programming,简称 OOP,是一种程序设计思想.OOP 把对象作为程序的基本单元,一个对象包含了数据和操作数据 ...

  10. python面向对象编程138讲_Python面向对象编程简单讲解

    学习目标: 1-面向对象编程 2-类和对象 3-对象的属性和方法 4-类的特性 Python面向对象编程 一种编程程序的设计思想,把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.把计算机 ...

最新文章

  1. 利用 createTrackbar 进行二值化
  2. 还有人不懂分布式锁的实现就把这篇文章丢给他
  3. 必看2019年学员信息系统项目管理师长篇备考经验
  4. STM32 之十 供电系统及内部参照电压(VREFINT)使用及改善ADC参考电压
  5. 软件工程开篇自我介绍
  6. asp.net core封装layui组件示例分享
  7. spring总结_Spring综合课程总结
  8. ppt护理文书流程图_护理文书书品管圈ppt
  9. linux-索引1909
  10. azure blob_从Azure Databricks访问Azure Blob存储
  11. vba下标越界9怎么解决_铝模气泡怎么解决?看9个常见问题防治
  12. 现代质量管理方法的应用思考和实践
  13. WIN7系统一个盘分多个盘的方法
  14. Neo4j 的一些使用心得
  15. win8怎么被远程计算机关闭,Win8系统局域网如何远程关机?Win8系统局域网远程关机的方法...
  16. 00003__爬拉勾网
  17. 为什么有斯坦福计算机科学博士学位的你找不到工作?
  18. 三星android pie更新,三星Android Pie更新路线图公布 Galaxy Note9需等明年二月
  19. filezilla定时上传_windows下定时利用bat脚本实现ftp上传和下载
  20. ipa解包打包工具_解压ipa软件包找到urlscheme

热门文章

  1. 软件项目的托管平台gitHub
  2. Mysql两个引擎对比
  3. 工具-VS插件Resharper快捷键
  4. (转)Google Fonts 的介绍与使用
  5. 第一章:WTL的5个W
  6. 2019-05-22 SperScan扫描器;SperScan附属工具
  7. 《简约之美:软件设计之道》总结
  8. CentOS7 yum方式安装MySQL5.7
  9. text-align 属性,输入框数字向右靠
  10. 加锁解锁PHP实现 -转载