Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12781
  • 博文数量: 5
  • 博客积分: 240
  • 博客等级: 二等列兵
  • 技术积分: 75
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-02 16:45
文章分类

全部博文(5)

文章存档

2012年(5)

我的朋友

分类: Python/Ruby

2012-09-04 10:57:39

7 更加抽象
7.1 对象的魔力
对象:可以看做数据(特性)以及由一系列可以存取,操作这些数据的方法所组成的集合
对象的优点:多态:对不同类的对象使用同样的操作
   封装:对外部隐藏对象的工作细节
   继承:以普通的类为基础建立专门的类的对象
7.11 多态
1.多态和方法
eg: from random import choice
x=choice(['Hello world',[1,2,'e','o','e']]) #choice从序列中随机选出元素
print x #Hello world
print x.count('e') #count:统计e出现的次数,1
上例中关键点在于不需要检测类型,只需知道x有个叫count的方法,带有一个字符作为参数,并返回整数值就够了
2.多态的多种形式
任何不知道对象是什么类型,但又要对象做点什么的时候,都会用到多态,很多内建运算符和函数都有多态的性质:
eg: 1+2
'fish'+'meat'
这里的+运算符对于数字和字符串都起到作用。
7.12 封装
封装和多态一样,使用对象而不知道其内部细节,因为它们都是抽象的原则,但是封装并不等同多态,多态可以让用户对于不知道是什么类的对象进行方法调用,
而封装是可以不用关心对象是如何构建而直接进行使用。
7.13 继承
如果已经有一个类,而又想建个非常类似的新类,比如有个shape类,可以在屏幕上画出指定形状,现需要创建一个叫rectangle的类,它不但能画形状还能计算形状的面积,
如果不想把shape里写好的方法再写一次,就可以让rectangle从shape类继承方法。
详见7.25

7.2 类和类型
7.21 类到底是什么
类:一种对象,所有的对象都属于某一个类,称为类的实例
比如:百灵鸟就是鸟类的实例,百灵鸟类是鸟类的子类,鸟类是百灵鸟类的超类
在面向对象的程序设计中,子类的关系是隐式的,因为一个类的定义取决于它所支持的方法,类的所有实例都会包含这些方法,所以所有的子类的所有实例也都有这些方法
定义子类只是定义更多的方法的过程。
比如:bird支持fly方法,penguin(bird的子类)可能会增加个eatfish方法,当创建penguin类时,可能会想要重写bird的fly:对于penguin来说,这个方法要么什么也不做,要么产生异常,因为penguin(企鹅)不会fly
7.22 创建自己的类
eg: class person:
def setName(self,name):
self.name=name
def getName(self):
return self.name
def greet(self):
print "Hi,I'm %s." % self.name

foo=person()
bar=person()
foo.setName('Lady Gaga')
bar.setName('Mr.Right')
foo.greet() #Hi,I'm Lady Gaga.
bar.greet() #Hi,I'm Mr.Right.
上例中的self,在调用foo的setName和greet函数时,foo自动将自己作为第一个参数传入函数中,没有self,成员方法就无法访问它们要对其特性进行操作的对象本身
7.23 特性、函数和方法
前例中的self参数事实上正是方法和函数的区别,方法将它们的第一个参数绑定到所属的实例上,如果将特性绑定到普通函数上,就不会有特殊的self参数
私有化:
程序可以从外部访问一个对象的特性,python并不直接支持私有方式,需要靠程序员把握在外部进行特性修改的时机。
让方法或者特性变为私有(从外部无法访问),只需在名字前加上双下划线__即可
eg: class Secretive:
def __inaccessible(self):
print 'bet you can not see me'
def accessible(self):
print 'the secret message is:'
self.__inaccessible()
s=Secretive()
#s.__inaccessible() #会报错
s.accessible() #the secret message is:bet you can not see me
__inaccessible无法从外界直接访问,但类内部还能使用
实际上还是有能从外部访问私有的方法:
s._Secretive__inaccessible() #bet you can not see me
前面带有下划线的名字都不会被带有*的imports语句导入(from module import *)
7.24 类的空间命名
def foo(x): return x*x
foo=lamba x:x*x
以上2个语句几乎等价
所有在class语句中的代码都在特殊的命名空间中执行--类命名空间,这个空间可由类内所有成员访问
eg: class MemberCounter():
member=0
def init(self):
MemberCounter.member+=1
print MemberCounter.member
m1=MemberCounter()
m1.init() #init用来初始化所有实例
m1.member #1
m2=MemberCounter()
m2.init()
m2.member #2
7.25 指定超类
子类可以扩展超类的定义,将其他类名写在class语句后的圆括号内可以指定超类
eg: >>> class Filter:
def init(self):
self.blocked=[]
def filter(self,sequence):
return [x for x in sequence if x not in self.blocked]

>>> class SPAMFilter(Filter): #SPAMFilter是Filter的子类
def init(self): #重写Filter中的init方法
self.blocked=['SPAM']

>>> f=Filter()
>>> f.init()
>>> f.filter([1,2,3])
[1, 2, 3]
>>> s=SPAMFilter()
>>> s.init()
>>> s.filter(['SPAM','SPAM','SPAM','SPAM','egg','bacon','SPAM'])
['egg', 'bacon']
上例中SPAMFilter有2个要点:
1.重写了Filter的init定义
2.filter方法的定义从Filter类中继承的,故不用定义
7.26 调查继承
如果想要查看一个类是否是另一个的子类,可以使用内建issubclass函数
eg: >>> issubclass(SPAMFilter,Filter)
True
>>> issubclass(Filter,SPAMFilter)
False
>>> SPAMFilter.__bases__ #想要知道已知类的基类,可以用__bases__
(,)
>>> f.__class__
#想知道一个对象属于哪个类,可以用__class__
>>> s.__class__
7.27 多个超类
eg: class Cal:
def calculate(self,expression):
self.value=eval(expression)
class Talk:
def talk(self):
print 'Hi,my value is ',self.value
class CT(Cal,Talk):
pass
tc=CT()
tc.calculate('5*5+5')
tc.talk()
上例行为被称为多重继承,但需注意:如果一个方法从多个超类继承(即有个具有相同名字的不同方法),那就需注意超类的顺序,先继承的方法会重写后继承的类的方法
如果上例中Cal类中也有个叫talk的方法,就会重写Talk中的talk方法
7.28 接口和内省
接口的概念和多态相关,在处理多态对象时,只要关系它的接口(或称‘协议’),即公开的方法和特性
检查所需方法是否已经存在:
hasattr(tc,'talk') #True
hasattr(tc,'Talk') #False
检查特性是否可以调用:
callable(getattr(tc,'talk',None)) #True,callable在3.0中已不可用,可使用hasattr(x,'__call__')

7.3 一些关于面向对象设计的思考
1.将属于一类的对象放在一起,如果一个函数操纵一个全局变量,那么两者最好都在类内作为特性和方法出现
2.不要让对象过于亲密,方法应该只关心自己实例的特性,让其他实例管理自己的状态
3.小心继承,尤其多重继承,在某些情况下会使问题变复杂,而且难以调试
4.简单,多数方法应能在30s内被读完(理解)
考虑需要什么类以及类要什么方法时:
1.写下问题的描述(程序要做什么),把所有名词、动词、形容词加下划线
2.对于所有名词,用作可能的类
3.所有动词,用作可能的方法
4.所有形容词,用作可能的特性
5.把所有方法和特性分配到类

7.4 小结
对象: 对象包括特性和方法,特性只是作为对象的一部分变量,方法则储存在对象内的函数中。绑定方法和函数的区别在于方法总是将对象作为自己的第一个参数,一般称self
类: 代表对象的集合,每个对象(实例)都有一个类,类的主要任务是定义它的实例会用到的方法



















阅读(403) | 评论(0) | 转发(0) |
0

上一篇:py基础教程 读书笔记 第6章 抽象

下一篇:没有了

给主人留下些什么吧!~~