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

原创 2016年06月01日 17:40:19

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

>>> _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):返回对象的类型

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《Python基础教程》学习笔记 Chp9 魔法方法、属性和迭代器

在Python中,有的名称会在前面和后面加上两个下划线(例如future),这种瓶邪表示名字有特殊含义,所以绝不要在自己的程序中使用这种名字。在Python中,有这些名字组成的集合所包含的方法称为魔法...

《Python基础教程》学习笔记 Chp8 异常

1.什么是异常 Python用异常对象(exception object)来表示异常情况。遇到错误后,会引发异常。如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(traceback)终止信息。例...

《Python基础教程》学习笔记之[D8]更加抽象——类

只做涂鸦笔记之用,如有疑议等问题可留言探讨。 #!/usr/bin/env python2.7 # -*- coding: utf-8 -*- # 面向对象 对象 object # 多态 封...
  • treesky
  • treesky
  • 2011年12月20日 11:24
  • 772

Python学习笔记【七】——《python基础教程》:: 更加抽象

python 更加抽象

《Python基础教程》学习笔记之[D7]抽象之函数定义,参数(一)

只做涂鸦笔记之用,如有疑议等问题可留言探讨。 #!/usr/bin/env python2.7 # -*- coding: utf-8 -*- # 简单闭包,闭包是一个复杂问题这里只是简单介...
  • treesky
  • treesky
  • 2011年12月19日 10:27
  • 949

《Python基础教程》学习笔记之[D6]抽象之函数定义,参数

只做涂鸦笔记之用,如有疑议等问题可留言探讨。 #!/usr/bin/env python2.7 # -*- coding: utf-8 -*- # 抽象 即是把现实世界变成成代码 # 斐波那契...
  • treesky
  • treesky
  • 2011年12月15日 20:44
  • 788

Python学习笔记【六】——《python基础教程》:: 抽象

第6章 抽象6.3. 创建函数 判断函数是否可调用。 Python3.0前,使用内建函数callable(func) Python3.0后,使用表达式hasattr(func, __call__)...

python基础教程_学习笔记7:条件、循环、其它语句

条件、循环、其它语句 print和import 随着更加深入地学习python,可能会出现这种感觉:有些自以为已经掌握的知识点,还隐藏着一些让人惊讶的特性。   使用逗号输出 打印多个表达式...

Python基础教程之第7章 更加抽象

D:\>python Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "...

python基础教程---更加抽象,类,继承多态封装

1.对象 对象基本可以看做数据(特性)以及由一系列可以存取,操作这些数据的方法所组成的集合 多态,不同类的对象使用同样的操作 封装,对外部世界隐藏对象的工作细节 继承,以普通的类为基础建立专门的类对象...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《Python基础教程》学习笔记 Chp7 更加抽象
举报原因:
原因补充:

(最多只允许输入30个字)