您的位置:首页 > 编程语言 > Python开发

读书笔记--《Python基础教程第二版》--第七章 更加抽象

2017-09-11 17:10 609 查看
7.1 对象的魔力
多态 不同的类的对象使用同样的操作
封装
继承

7.1.1 多态
1、多态和方法
>>>object.getPrice()

>>> 'abc'.count('a')
1
>>> [1,2,'a'].count('a')
1
>>> from random import choice
>>> x=choice(['Hello world!',[1,2,'e','e',4]])
>>> x.count('e')
1
>>> x=choice(['Hello world!',[1,2,'e','e',4]])
>>> x.count('e')
2


python的多态不需要做类型检测,只要有相同的方法就行,python的多态其实有点像java的函数重载
>>> def add(x,y):
...   return x + y
...

>>> add(1,2)
3

>>> add('Fish','License')
'FishLicense'

>>> def length_message(x):
...   print "The length of",repr(x),"is",len(x)
...

>>> length_message('Fnord')
The length of 'Fnord' is 5

>>> length_message([1,2,3])
The length of [1, 2, 3] is 3


很多系统函数和运算符都是多态的

唯一能够销毁多态的就是使用函数显示做类型检测,比如type,isinstance、issubclass,但是尽量避免消除

7.1.2 封装
7.1.2 继承
7.2 类和类型
7.2.1 类到底是什么
7.2.2 创建自己的类
class Person:
def setName(self,name):
self.name=name

def getName(self):
return self.name

def greet(self):
print "Hello world! I'm %s" % self.name

>>> foo=Person()
>>> bar=Person()

>>> foo.setName('Luke Skywalker')
>>> bar.setName('Anakin Skywaler')

>>> foo.greet()
Hello world! I'm Luke Skywalker

>>> bar.greet()
Hello world! I'm Anakin Skywaler


self 表示对象本身的引用,对象的属性和方法可以动态的添加

>>> foo.name
'Luke Skywalker'

>>> bar.name
'Anakin Skywaler'

>>> bar.name='Yoda'
>>> bar.greet()
Hello world! I'm Yoda


7.2.3 特性、函数和方法

>>> class Class:
...   def method(self):
...     print 'I hava a self!'
...
>>>
>>> def function():
...   print "I don't ..."
...
>>> instance=Class()
>>> instance.method()
I hava a self!

>>> instance.method=function
>>> instance.method()
I don't ...


#可以绑定一个不存在的方法
>>> instance.method1=function
>>> instance.method1()
I don't ...


self参数并不取决于调用方法的方式

>>> class Bird:
...   song='Squaawk!'
...   def sing(self):
...     print self.song
...

>>> bird=Bird()
>>> bird.sing()
Squaawk!
>>> birdsong=bird.sing #用另外一个变量调用也可以
>>> birdsong()
Squaawk!

再论私有化,前面带有两个__的属性或者方法即为私有方法

>>> class Secretive:
...   def __inaccessible(self):
...     print "Bet you can't see me..."
...   def accessiable(self):
...     print "The secret message is :"
...     self.__inaccessible()
...
>>> s=Secretive()
>>> s.__inaccessible()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Secretive instance has no attribute '__inaccessible'

>>> s.accessiable()
The secret message is :
Bet you can't see me...

通过其他方式依然可以访问得到

>>> Secretive._Secretive__inaccessible
<unbound method Secretive.__inaccessible>
>>> s._Secretive__inaccessible()
Bet you can't see me...

前面有下划线的方法,不会被from module import * 导入

7.2.4 类的命令空间
位于class语句中的代码都在类的命名空间,定义类的过程其实就是在执行语句块,这个命令空间可由类内所有成员访问

>>> def foo(x): return x*x
...
>>>
>>> foo = lambda x:x*x   #lambda 用来定义简单的函数


>>> class MemberCounter:
...   members=0
...   def init(self):
...     MemberCounter.members +=1
...

>>> m1=MemberCounter()
>>> m1.init()
>>> MemberCounter.members
1
>>> m2=MemberCounter()
>>> m2.init()

>>> MemberCounter.members
2

>>> m1.members
2
>>> m2.members
2

新的numbers值被写到m1的特性中,屏蔽了类范围的变量,新的number属性属于对象的变量了
>>> m1.members='Tow'
>>> m1.members
'Tow'
>>> m2.members
2
>>> MemberCounter.members
2

7.2.5 指定超类
#!/usr/bin/python
#coding:utf-8
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):
def init(self): #重写Filter超类中的init方法
self.blocked=['SPAM']


f=Filter()
f.init()
print f.filter([1,2,3])


s=SPAMFilter()
s.init()
print s.filter(['SPAM','SPAM','eggs','bacon','SPAM','SPAM'])


[1, 2, 3]
['eggs', 'bacon']


SPAMFilter两个要点:
1、重写了Filter的init()方法
2、继承了filter方法

7.2.6 调查继承
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):
def init(self):
self.blocked=['SPAM']


#判断一个类是否是另一个的子类
>>> issubclass(SPAMFilter,Filter)
True
>>> issubclass(Filter,SPAMFilter)
False


#查看已知类的基类
>>> SPAMFilter.__bases__
(<class __main__.Filter at 0x7f087de34650>,)
>>> Filter.__bases__
()


#isinstance检查对象是否为一个类的实例
>>> s=SPAMFilter()
>>> isinstance(s,SPAMFilter)
True
>>> isinstance(s,Filter)
True
>>> isinstance(s,str)
False


>>> type(s)
<type 'instance'>


#查看一个对象属于哪个类
>>> s.__class__
<class __main__.SPAMFilter at 0x7f087de345f0>


7.2.7 多个超类
>>> class Calculator:
...     def calculate(self,expression):
...         self.value=eval(expression)
...
>>> class Talker:
...     def talk(self):
...         print 'Hi,my value is ',self.value
...
>>> class TalkingCalculator(Calculator,Talker):
...     pass
...
>>> tc=TalkingCalculator()
>>> tc.calculate('1+2*3')
>>> tc.talk()
Hi,my value is  7


注意:尽量少用多重继承
如果一个方法从多个超类继承,先继承的类中的方法会重新后继承的类中的方法

7.2.8 接口和内省

Python中,不用显示的指定对象必须包含哪些方法才能作为参数接收,不用显示的编写接口
>>> hasattr(tc,'talk')
True
>>> hasattr(tc,'fnord')
False
>>>


#getattr可以指定一个默认值,如果不存在,则指定一个默认值
>>> callable(getattr(tc,'talk',None))
True
>>> callable(getattr(tc,'fnord',None))
False
>>> setattr(tc,'name','Mr.Gumby')
>>> tc.name
'Mr.Gumby'


#查看对象内所有存储的值
>>> tc.__dict__
{'name': 'Mr.Gumby', 'value': 7}


如果要看对象由什么组成的,可以看看inspect模块
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ja