《Python基础教程》学习笔记 Chp7 更加抽象

多态
多态意味着不知道变量所引用的对象类型是什么,还是能对它进行操作,而它也会根据对象(或类)类型的不同而表现出不同的行为。
封装
封装是指向程序中的其他部分隐藏对象的具体实现细节的原则。
创建自己的类

>>> _metaclass_ = type
>>> 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('Alice')
>>> bar.setName('Bobby')
>>> foo.greet()
Hello , world ! I'm Alice.
>>> bar.greet()
Hello , world ! I'm Bobby.

注: metaclass = type,在新式类的语法中才需要加。这里self参数是对于对象自身的引用。其中setName等叫做类的方法。
特性、函数和方法
self参数事实上是方法和函数的区别,方法将它们的第一个参数绑定到所属的实例上,因此我们无需显示提供该参数。当然也可以将特性绑定到一个普通函数上,这样就不会有特殊的self参数了:

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

self参数并不依赖于调用方法的方式,前面我们使用的是instance.method(实例.方法)的形式,可以随意使用其他变量引用同一个方法:

>>> class Class:
...     def method(self):
...         print 'I have a self'
...         
>>> cls = Class()
>>> cls.method()
I have a self
>>> method = cls.method
>>> method()
I have a self

注:尽管最后一个方法调用看起来于函数调用十分相似,但是变量method引用绑定方法cls.method上,也就意味着这还是会对self参数进行访问(也就是说,它仍旧绑定到类的相同实例上)。
私有化
为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上双下划线即可。例:

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

类的内部定义中,所有的双下划线开始的名字都被‘翻译’成前面加上单下划线和类名的形式。如:

>>> Secretive._Secretive__inaccessible
<unbound method Secretive.__inaccessible>

因此上例中的私有化方法可以如下所示进行访问:

>>> s._Secretive__inaccessible()
Bet you can't see me ...

如果不需要使用这种方法但是又想让其他对象不要访问内部数据,那么可以使用单下划线。例:

>>> class Secretive:
...     def _inaccessible(self):
...         print "Bet you can't see me ..."
...         
>>> s = Secretive()
>>> s._Secretive__inaccessible()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AttributeError: Secretive instance has no attribute '_Secretive__inaccessible'
>>> s._Secretive_inaccessible()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AttributeError: Secretive instance has no attribute '_Secretive_inaccessible'

类的命名空间
例:

>>> class MemberCounter:
...     members = 0
...     def init(self):
...         MemberCounter.members+=1
...         
>>> m1 =  MemberCounter()
>>> m1.init()
>>> MemberCounter.members
1
>>> m2 = MemberCounter()
>>> m2.init()
>>> MemberCounter.members
2
>>> m2.members
2
>>> m1.members = 'two'
>>> m1.members
'two'
>>> m2.members
2

分析说明:类中定义了一个可供所有成员(实例)访问的变量members,用来计算类的成员数量(我们可以把它理解为全局变量),然后又在实例m1中重新绑定了members的值(此时相当于是局部变量,所以屏蔽了类范围内的变量)。
指定超类
例:

>>> 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', 'eggs', 'bacon', 'SPAM'])
['eggs', 'bacon']

检查继承
如果要查看一个类是否是另一个类的子类,可以使用内建函数的issubclass函数。例:

>>> issubclass(SPAMFilter, Filter)
True
>>> issubclass(Filter, SPAMFilter)
False

如果想要知道已知类的基类(们),可以直接使用它的特殊特性_bases_。例:

>>> SPAMFilter.__bases__
(<class __main__.Filter at 0x02324D18>,)
>>> Filter.__bases__
()

使用isinstance方法检查一个对象是否是一个类的实例。例:

>>> isinstance(s, SPAMFilter)
True
>>> isinstance(s, Filter)
True
>>> isinstance(f, SPAMFilter)
False

可以使用_class_特性知道一个对象属于哪个类。例:

>>> s.__class__
<class __main__.SPAMFilter at 0x02324C38>
>>> f.__class__
<class __main__.Filter at 0x02324D18>

多个超类
Python中支持多重继承,即一个类可以有多个超类。当使用多重继承时,如果一个方法从多个超类继承(也就是说有两个具有相同名字的不同方法),那么必须要注意一下超类的顺序(在class语句中):先继承的类中的方法会重写后继承的类中的方法,这种访问超类的顺序为MRO(Method Resolution Order,方法判定顺序)。例:

>>> class Calculator:
...     def calculator(self, expression):
...         self.value = eval(expression)
...     def talk(self):
...         print 'Hi, my value is : ', self.value
...         
>>> class Talker:
...     def talk(self):
...         print 'Hi, now you can get my value is : ', self.value
...         
>>> class TalkingCalculator(Calculator, Talker):
...     pass
... 
>>> tc = TalkingCalculator()
>>> tc.calculator('1+2*3')
>>> tc.talk()
Hi, my value is :  7
>>> class TalkingCalculator(Talker, Calculator):
...     pass
... 
>>> tc1 = TalkingCalculator()
>>> tc1.calculator('1+2*3')
>>> tc1.talk()
Hi, now you can get my value is :  7

接口和内省
可以使用hasattr方法检查所需方法是否已经存在。例:

>>> hasattr(tc, 'talk')
True
>>> hasattr(tc, 'finder')
False

可以使用callable方法检查所需的方法是否可调用。例:

>>> callable(getattr(tc, 'tall', None))
False
>>> callable(getattr(tc, 'talk', None))
True

本章新函数
callable(object): 确定对象是否可调用(比如函数或者方法)
getattr(object,name[, default]): 确定特性的值,可选择提供默认值
hasattr(object,name):确定对象是否有给定的特性
isinstance(object,class):确定对象是否是类的实例
issubclass(A,B):确定A是否为B的子类
random.choice(sequence):从非空徐磊中随机选择元素
setattr(object,name,value):设定对象的给定特性为value
type(object):返回对象的类型

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lzh398651363/article/details/51557743
文章标签: python
个人分类: Python
上一篇《Python基础教程》学习笔记 Chp6 抽象
下一篇《Python基础教程》学习笔记 Chp8 异常
想对作者说点什么? 我来说一句

Chp7

2014年05月29日 4.26MB 下载

python基础教程

2018年05月30日 33.07MB 下载

Python基础教程第二版

2018年03月15日 33.18MB 下载

动态规划整理笔记,分享了

2008年12月11日 14KB 下载

java之抽象与分类

2018年05月22日 4.1MB 下载

python基础教程第三版

2018年02月07日 10.15MB 下载

python基础教程第三版 文字版

2018年03月22日 3.62MB 下载

Python基础教程 PDF大全包

2018年05月26日 2.64MB 下载

没有更多推荐了,返回首页

关闭
关闭