文档章节

python 第13章:面向对象编程

finndai
 finndai
发布于 2016/11/15 18:40
字数 3246
阅读 76
收藏 1

1. 类是对象的定义,而实例是“真正的产物”,它存放了类中所定义的对象的具体信息

方法:方法为类的属性,除了静态方法以外,方法必须由实例调用

self参数:它在所有的声明中都存在,代表实例本身,方法的调用通过self关联到类里

创建实例:靠继承来进行子类化是创建和定制新型类型的一种方式,新的类将保持已存在类所有的属性,不会影响到原来的类

2.面向对象编程

常用术语: 封装/接口:描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数。

                    多态:多态的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们的类。多态表明了动态绑定的存在,允许重载及运行时类型确定和验证

4.类

类属性:属性就是属于另一个对象的数据或者函数元素,可以通过我们熟悉的句点属性标识法来访问

 

    4.1·类的数据属性

       数据属性仅仅是所定义的类的变量。静态成员通常用来跟踪与类相关的值,大多数情况下,你会考虑用实例属性,而不是类属性。

    4.2Methods

    方法仅仅是一个作为类定义一部分定义的函数(这使得方法成为类属性),并且只能通过实例来调用(我并没有把静态方法和类方法当作方法,仅仅认为它们只是函数---独立于类对象)

    4.3查看类的属性

    dir(myclass)  myclass.__dict__

   13.5实例

        13.5.1 初始化:通过调用类对象来创建实例

        13.5.2__init__() 构造器方法

            类被调用,实例化的第一步是创建实例对象。一旦对象创建了,python检查是否实现了__init__()方法、若没有:对实例不会施加特别的操作。

        13.5.3__new__()构造器方法

            实例化不可变对象

        13.5.4__del__()解构器方法

            python 具有垃圾回收机制,这个函数直到所有的引用都被清除掉后才会执行

13.6实例属性

        设置实例的属性可以在实例创建后任意时间进行,也可以在能够访问实例的代码中进行。构造器__init()__是设置这些属性的关键点之一

        能够在“运行时”创建实例属性,是python类的优秀特性之一。缺点是:属性在条件语句中创建,如果该条件语句块并未被执行,属性也就不存在。

__int__()不应该返回任何对象(应当为none)

        13.6.2 查看实例属性

            dir()    __dict__      __class__

        13.6.5 实例属性VS类属性

            类属性可通过类或实例来访问。当然,通过实例访问一个类属性时,只是建立一个临时的类属性引用,当实例消失后,对应的类属性也消失

             不推荐使用实例来访问类属性。虽然方法也被称为类属性,但方法特殊就特殊在于:它通过self参数绑定到了实例对象去了,所以方法通常要用到实例来调用,用类调用不行-----原因也挺简单的,方法中操作的是实例数据,一般很少操作类数据属性,所以要用实例来调用。

13.7 绑定和类调用

方法三要点:·1.方法仅仅是类内部定义的函数

                        2.方法只有在其属性拥有实例的时候,才能被调用

                          3.任何方法定义的第一个参数都是变量self

13.7.1调用绑定方法

        通过实例来调用

13.7.2调用非绑定方法

        继承时构造器的实现是调用非 绑定方法

13.8静态方法和类方法

    并不推荐使用静态方法,一般来说,我们可以使用模块函数来达到目的。

13.9组合

让不同的类混合并加入其他类中去

13.10子类和派生

设计相同的类,但是有一些不同的功能的时候,派生是一种更好的方法

OOP的更强大的功能体现在能够使用一个已经定义好的类,扩展它或者对他进行修改,而不会影响系统中使用现存类的其他代码片段。

13.11继承

13.11.4多重继承

        python允许子类继承多个基类,这种特性就是通常所说的多重继承。

        在python2.2以前的版本,算法非常简单:深度优先,从左至右进行搜索,取得在子类中使用的属性。

        新式类,广度优先,从左至右。

        新式类有一个__mro__属性,告诉你查找顺序。

13.12.类、实例和其他对象的内建函数

        13.12.1 issubclass()

                        issubclass()布尔函数判断一个类是另一个类的子类或者子孙类

                          issubclass(sub,sup)

          13.12.2 isinstance()

                           isinstance()布尔函数判定一个对象是否是另一个给定类的实例

                           isinstance(obj1,obj2)

            13.12.3 hasattr()  getattr() setattr() delattr()

                            hasattr()函数是boolean型的,它的目的就是为了决定一个对象是否有一个特定的属性,一般用于访问某属性前先做一个检查。

                              getattr()和setattr()函数相应的取得和赋值给对象的属性,getattr()会在你试图读取一个不存在的属性时,引发AttributeError异常,

                              除非给出那个可选的默认参数。setattr()将要么加入一个新的属性,要么取代一个已存在的属性。而delattr()函数会从一个对象中删除属性。

            13.12.4 dir()

                       dir()列出一个模块所有属性的信息

            13.12.5 super()

                        super()函数的目的就是找出相应的父类。

              13.12.6 vars()

                          vars内建函数与dir()相似,只是给定的对象参数必须要有一个__dict()__的属性

13.16新式类的高级特性

            13.16.3 特殊方法__getattribute__()

                python类有一个名为__getattr__()的特殊方法,它仅当属性不能在实例的__dict__或它的类(类的__dict__),或者祖先类(其__dict__)中找到时,才被调用。

                __getattribute__的作用是:当属性被访问时,它就一直都可以被调用,而不局限于不能找到的情况。

            13.16.5

                    元类可以认为元类的实例是类,元类一般用于创建类(类工厂)

                    __metaclass__属性:如果类中有__metaclass__属性就用来创建类,没有就在父类中查找

 

 

13.18练习

13-1 程序设计。请列举一些面向对象编程与传统旧的程序设计形式相比的先进之处。

            易维护,增加代码重复利用率,效率高、易扩展

13-2函数和方法的比较。函数和方法之间的区别是什么?

函数是一段代码。通过名字调用,它能将一些数据传递进去进行处理,然后返回一些数据。也可以

没有返回值

方法也是一段代码,也通过名字来调用,但它跟一个对象相关联,方法和函数大致上是相同的,但有2个主要的不同

之处:

                1.方法中的数据是隐式传递的

                 2.方法可以操作类内部的数据

13-3

13-3. 对类进行定制。写一个类,用来将浮点数值转换为金额。在本练习里,我们使用美国货币,但读者也可以自选任意货币。
基本任务: 编写一个dollarize()函数,它以一个浮点数值作为输入,返回一个字符串形式的金额数。比如说:dollarize(1234567.8901) ==> ‘$1,234,567.89.dollarize()返回的金额数里应该允许有逗号(比如1,000,000),和美元的货币符号。如果有负号,它必须出现在美元符号的左边。完成这项工作后,你就可以把它转换成一个有用的类,名为MoneyFmt。

#-*-coding:utf-8-*-
class MoneyFmt(object):
    def __init__(self, value=0.0):
        self.value=float(value)
    def update(self, value=None):
        self.value = float(value)
    def __str__(self):
        if self.value>0:
            sign = '$'
        else:
            sign = '-$'
        return sign + str(round(abs(self.value), 2))
    def __repr__(self):
            return repr(self.value)
    def __nonzero__(self):
        return self.value!=0

cash = MoneyFmt(1234567.8901)
print cash

13-4 用户注册。建立一个用户数据库(包括登录名、密码和上次登录时间戳)类(参考练习7-5和9-12),来管理一个系统,该系统要

求用户在登录后才能访问某些资源。这个数据库类对用户进行管理,并在实例化操作时加载之前保存的用户信息,提供访问函数来添加或更新数据库的信息。在数据修改后,数据库会在垃圾回收时将新信息保存到磁盘。

import shelve
import os
import time

class UserData(object):
    def __init__(self,dbfile):
        self.db={}
        if os.path.exists(dbfile):
            self.db=shelve.open(dbfile,'r')
        self.dbfile=dbfile
    def __del__(self):
        data = shelve.open(self.dbfile,'c')
        data.update(self.db)
        data.close()
    def update(self,name,password):
        self.db[name] = [password,time.time()]
    def delete(self,name):
        self.db.pop(name)
    def login(self,name,password):
        if self.db.get(name,none)[0]==password:
            self.db[name][1]=time.time()
            return True
        else:
            return False
    def listall(self):
        for name in self.db:
            print name,self.db[name][0],time.ctime(self.db[name][1])

13-5几何. 创建一个由有序数值对(x, y) 组成的Point 类,它代表某个点的X 坐标和Y 坐标。X 坐标和Y 坐标在实例化时被传递给构造器,如果没有给出它们的值,则默认为坐标的原点。

#-*-coding:utf-8-*-
class Point(object):
    def __init__(self,x=0,y=0):
        self.x=x
        self.y=y
    def __str__(self):
        return "(%d,%d)" %(self.x,self.y)

    __repr__=__str__

m=Point(4,5)
print m

13-6. 几何. 创建一个直线/直线段类。除主要的数据属性:一对坐标值(参见上一个练习)外,它还具有长度和斜线属性。你需要覆盖__repr__()方法(如果需要的话,还有__str__()方法),使得
代表那条直线(或直线段)的字符串表示形式是由一对元组构成的元组,即,((x1, y1), (x2, y2)).

#-*-coding:utf-8-*-
import math
class Point(object):
    def __init__(self,x=0,y=0):
        self.x=x
        self.y=y
    def __str__(self):
        return "(%d,%d)" %(self.x,self.y)

    __repr__=__str__

class Line(object):
    def __init__(self,x1=0,y1=0,x2=0,y2=0):
        self.p1=Point(x1,y1)
        self.p2=Point(x2,y2)
    def __str__(self):
        return"(%s,%s)" %(str(self.p1),str(self.p2))
    def slope(self):
        k=(self.p1.y-self.p2.y)/(self.p1.x-self.p2.x)
        return k
    def length(self):
        l=math.sqrt((self.p1.y-self.p2.y)**2+(self.p1.x-self.p2.x)**2)
        return l

m=Line(2,3,4,5)
print m
print m.slope()
print m.length()

 

13-7数据类。提供一个time 模块的接口,允许用户按照自己给定时间的格式,比如:“MM/DD/YY,” “MM/DD/YYYY,” “DD/MM/YY,” “DD/MM/ YYYY,” “Mon DD, YYYY,” 或是标准
的Unix 日期格式:“Day Mon DD, HH:MM:SS YYYY” 来查看日期。你的类应该维护一个日期值,并用给定的时间创建一个实例。如果没有给出时间值,程序执行时会默认采用当前的系统时间。还包
括另外一些方法:update() 按给定时间或是默认的当前系统时间修改数据值     display() 以代表时间格式的字符串做参数,并按照给定时间的格式显示:
'MDY' ==> MM/DD/YY
'MDYY' ==> MM/DD/YYYY
'DMY' ==> DD/MM/YY
'DMYY' ==> DD/MM/YYYY
'MODYY' ==> Mon DD, YYYY

import time  
  
class TimeFmt(object):  
  
    def __init__(self, time=time.time()):  
        self.__time = time  
  
    def update(self, time=time.time()):  
        self.__time = time  
  
    def display(self, fmt=None):  
        fmtdb = {}  
        fmtdb['MDY'] = '%m/%d/%y'  
        fmtdb['MDYY'] = '%m/%d/%Y'  
        fmtdb['DMY'] = '%d/%m/%y'  
        fmtdb['DMYY'] = '%d/%m/%Y'  
        fmtdb['MODYY'] = '%m %d, %Y'  
        if fmt in fmtdb:  
            t = time.localtime(self.__time)  
            print time.strftime(fmtdb[fmt], t)  
        else:  
            print time.ctime(self.__time)  

13-8 实现一个堆栈类,类中应该有push()和pop()方法,还有一个isempty()方法,如果堆栈是空的,返回布尔值1,否则返回0。

class stack(object):
    def __init__(self):
        self.ls=[]
    def push(self,i):
        self.ls.append(i)
    def pop(self):
        if not self.isempty():
            self.ls.pop()
    def isempty(self):
        return len(self.ls)==0
    def peek(self):
        return self.ls[-1]
    def __str__(self):
        return str(self.ls)
    __repr__=__str__
sta=stack()
sta.push(1)
sta.push(3)
print sta
sta.pop()
print sta
sta.push(5)
print sta
print sta.peek()

13-9.队列类。实现一个队列类,这个类必须支持下面几种方法:enqueue()在队列的尾部加入一个新的元素,dequeue()在队列的头部取出一个元素,返回它并且把它从列表中删除。\

#-*-coding:utf-8-*-
class queue(object):
    def __init__(self):
        self.ls=[]
    def __str__(self):
        return str(self.ls)
    def enqueue(self,i):
        self.ls.append(i)
    def dequeue(self):
        self.ls.pop(0)

QE=queue()
QE.enqueue(5)
QE.enqueue(7)
print QE
QE.dequeue()
print QE

13-10堆栈和队列。编写一个类,定义一个能够同时具有堆栈(FIFO)和队列(LIFO)操作行为的数据结构。这个类和Perl 语言中数组相像。需要实现四个方法:
shift()         返回并删除列表中的第一个元素,类似于前面的dequeue()函数。
unshift()      在列表的头部"压入"一个新元素
push()         在列表的尾部加上一个新元素,类似于前面的enqueue()和push()方法。
pop()         返回并删除列表中的最后一个元素,与前面的pop()方法完全一样。

                     按照13-8和13-9做就行  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
finndai
粉丝 1
博文 35
码字总数 38131
作品 0
南京
私信 提问
买《Python从小白到大牛》专题视频课程,送配套纸质图书

经过一年多时间的呕心沥血,Python立体化图书——《Python从小白到大牛》即将与大家见面了。所谓立体化图书包括:电子图书、视频、课件和服务等内容。 《Python从小白到大牛》纸质图书将于9...

tony关东升
07/23
0
0
那些年,我们读过的python!

Python是一个强大、快速、易学、友好、开源的脚本语言。Hacker必备的语言之一。 Python - 历史由来 Python 是一种开源的面向对象的脚本语言,它起源于1989年末,当时,CWI(阿姆斯特丹国家数...

生气的散人
2014/03/21
1K
2
Python高级编程和异步IO并发编程

Python高级编程和异步IO并发编程 网盘地址:https://pan.baidu.com/s/1eB-BsUacBRhKxh7qXwndMQ 密码: tgba 备用地址(腾讯微云):https://share.weiyun.com/5Z3x9V0 密码:7cdnb2 针对Pytho...

人气王子333
04/23
0
0
Python这么强大, 怎样才能快速入坑?

作为一种年轻的编程语言,Python为何能在短短几年的时间内就以迅雷不及掩耳之势驰骋编程界?答案很简单,在人工智能时代,AlphaGo 都在使用的 Python语言,是最接近 AI 的编程语言。 随着Pyt...

bodasisiter
08/23
0
0
Python编程实践 学习笔记

Practical Programming-An Introduction to Computer Science Using Python 这本书是Jennifer Campbell等著,唐学韬(汕头大学)译,全书300页,虽内容不多,但个人认为译者比较负责,如未统一...

Honghe
2013/01/04
0
1

没有更多内容

加载失败,请刷新页面

加载更多

jquery通过id显示隐藏

var $div3 = $('#div3'); 显示 $div3.show(); 隐藏 $div3.hide();

yan_liu
45分钟前
1
0
《乱世佳人》读书笔记及相关感悟3900字

《乱世佳人》读书笔记及相关感悟3900字: 之前一直听「荔枝」,后来不知怎的转向了「喜马拉雅」,一听就是三年。上班的时候听房产,买房了以后听装修,兴之所至时听旅行,分手后听亲密关系,...

原创小博客
48分钟前
1
0
大数据教程(9.6)map端join实现

上一篇文章讲了mapreduce配合实现join,本节博主将讲述在map端的join实现; 一、需求 实现两个“表”的join操作,其中一个表数据量小,一个表很大,这种场景在实际中非常常见,比如“订单日志...

em_aaron
今天
1
0
cookie与session详解

session与cookie是什么? session与cookie属于一种会话控制技术.常用在身份识别,登录验证,数据传输等.举个例子,就像我们去超市买东西结账的时候,我们要拿出我们的会员卡才会获取优惠.这时...

士兵7
今天
1
0
十万个为什么之为什么大家都说dubbo

Dubbo是什么? 使用背景 dubbo为什么这么流行, 为什么大家都这么喜欢用dubbo; 通过了解分布式开发了解到, 为适应访问量暴增,业务拆分后, 子应用部署在多台服务器上,而多台服务器通过可以通过d...

尾生
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部