重新看Python——一、面向对象

来源:互联网 发布:克莱汤普森生涯数据 编辑:程序博客网 时间:2024/06/05 11:44

编程模式的分类

  • 面向过程:根据业务逻辑从上到下写垒代码
    以代码块为单位,将之前实现的代码块复制到现需功能处。
while Trueif 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. 封装

  1. 通过对象直接调用被封装的内容
  2. 通过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