重新看Python——一、面向对象
来源:互联网 发布:克莱汤普森生涯数据 编辑:程序博客网 时间:2024/06/05 11:44
编程模式的分类
- 面向过程:根据业务逻辑从上到下写垒代码
以代码块为单位,将之前实现的代码块复制到现需功能处。
while True: if cpu利用率 > 90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 > 80%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
相比于面向过程而言增强代码的重用性和可读性
def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接while True: if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
- 面向对象:对函数进行分类和封装,让开发“更快更好更强…”
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能,对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
# 创建类class Foo: def Bar(self): print 'Bar' def Hello(self, name): print 'i am %s' %name# 根据类Foo创建对象objobj = Foo()obj.Bar() #执行Bar方法obj.Hello('wupeiqi') #执行Hello方法
面向对象的三大过程
1. 封装
- 通过对象直接调用被封装的内容
- 通过self间接调用被封装的内容
_ _ init_ _为构造方法
class Foo: def __init__(self, name, age): self.name = name self.age = age def detail(self): print self.name print self.ageobj1 = Foo('wupeiqi', 18)obj1.detail() # 方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18obj2 = Foo('alex', 73)obj2.detail() # 此时方法内部的 self = obj2,即:self.name 是 alex ; self.age 是 78
2.继承
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
class Animal: def eat(self): print "%s 吃 " %self.name def drink(self): print "%s 喝 " %self.name def shit(self): print "%s 拉 " %self.name def pee(self): print "%s 撒 " %self.nameclass Cat(Animal): def __init__(self, name): self.name = name self.breed = '猫' def cry(self): print '喵喵叫'class Dog(Animal): def __init__(self, name): self.name = name self.breed = '狗' def cry(self): print '汪汪叫'# ######### 执行 #########c1 = Cat('小白家的小黑猫')c1.eat()c2 = Cat('小黑的小白猫')c2.drink()d1 = Dog('胖子家的小瘦狗')d1.eat()
对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
1、Python的类可以继承多个类,Java和C#中则只能继承一个类
2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先(经典类)和广度优先(新式类)
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
经典类例子:
class D: def bar(self): print 'D.bar'class C(D): def bar(self): print 'C.bar'class B(D): def bar(self): print 'B.bar'class A(B, C): def bar(self): print 'A.bar'a = A()# 执行bar方法时# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错# 所以,查找顺序:A --> B --> D --> C# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了a.bar()
新式类例子:
class D(object): def bar(self): print 'D.bar'class C(D): def bar(self): print 'C.bar'class B(D): def bar(self): print 'B.bar'class A(B, C): def bar(self): print 'A.bar'a = A()# 执行bar方法时# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错# 所以,查找顺序:A --> B --> C --> D# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了a.bar()
经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
3.多态
class Person(object): def __init__(self,name,sex): self.name = name self.sex = sex def print_title(self): if self.sex == "male": print("man") elif self.sex == "female": print("woman")class Child(Person): # Child 继承 Person def print_title(self): if self.sex == "male": print("boy") elif self.sex == "female": print("girl")May = Child("May","female")Peter = Person("Peter","male")print(May.name,May.sex,Peter.name,Peter.sex)May.print_title()Peter.print_title()
当子类和父类都存在相同的 print_title()方法时,子类的 print_title() 覆盖了父类的 print_title(),在代码运行时,会调用子类的 print_title()
这样,我们就获得了继承的另一个好处:多态。
多态的好处就是,当我们需要传入更多的子类,例如新增 Teenagers、Grownups 等时,我们只需要继承 Person 类型就可以了,而print_title()方法既可以不重写(即使用Person的),也可以重写一个特有的。这就是多态的意思。调用方只管调用,不管细节,而当我们新增一种Person的子类时,只要确保新方法编写正确,而不用管原来的代码。这就是著名的“开闭”原则:
- 对扩展开放(Open for extension):允许子类重写方法函数
- 对修改封闭(Closed for modification):不能修改父类中的方法,不重写就直接是使用父类的方法
类的属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods
class JustCounter: __secretCount = 0 # 私有变量 publicCount = 0 # 公开变量 def count(self): self.__secretCount += 1 self.publicCount += 1 print self.__secretCountcounter = JustCounter()counter.count()counter.count()print counter.publicCountprint counter.__secretCount # 报错,实例不能访问私有变量
单下划线、双下划线、头尾双下划线说明:
- _ _foo_ _: 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。
- _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
- __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了
参考文献
菜鸟教程
伯乐在线
http://www.cnblogs.com/feeland/p/4419121.html
- 重新看Python——一、面向对象
- 设计模式(一)——重新认识面向对象
- python——面向对象
- python基础—面向对象
- 面向对象的python(一)
- python面向对象(一)
- [Python]面向对象编程(一)
- Python面向对象(一)
- python面向对象(一)
- python面向对象(一)
- java—面向对象、一
- 重新认识面向对象
- 面向对象(一)—关于面向对象的那些事
- 【面向对象】——编译时看父类,运行时看子类
- java必备——通过异常处理看面向对象
- 关于python——面向对象开发
- python之路——面向对象
- Python类——面向对象程序设计
- 用OpenAI的“后经验重放”来解决算法环境适应问题 | 2分钟读论文
- <C++>预编译处理
- 神经网络中容易被忽视的基础知识
- Thymeleaf判断集合是否为空
- 玩机器学习要知道哪些开源数据库?
- 重新看Python——一、面向对象
- 【回顾】用于文档理解的面向对象神经规划
- 如何使用高大上的方法调参数
- 【回顾】神经霍克斯过程:一个基于神经网络的自调节多变量点过程
- 【预告】中科院博士:迁移学习的发展与现状 | 公开课
- 【回顾】Deep Learning 读书分享:深度模型中的优化
- oracle的plsql,checks是什么?干什么用的?
- 北交大博士:强化学习与策略评估 | GAIR大讲堂
- 当前深度学习和 SLAM 结合有哪些比较好的论文