《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基础教程第七章学习笔记——更加抽象

7 更加抽象—创建自己的对象 前面讲了: Python主要的内建对象类型(数字、字符串、列表、元组和字典) 内建函数和标准库的用法 自定义函数的方式 本章主讲: 创建自己的对象(尤其是类型或者被称为类...
  • youngersteral
  • youngersteral
  • 2017年09月18日 20:38
  • 163

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

python 更加抽象
  • heli200482128
  • heli200482128
  • 2017年07月11日 17:50
  • 227

<<Python基础教程>>学习笔记 | 第07章 | 更加抽象

Python:面向对象的编程语言,多态,封装,继承三个主要特性 多态:来自希腊语,意味着有多种形式。 >>> from random import choice >>> x = choice(['He...
  • Jerry_1126
  • Jerry_1126
  • 2014年09月23日 21:02
  • 1116

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

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

python基础教程_学习笔记12:充电时刻——模块

充电时刻——模块 python的标准安装包括一组模块,称为标准库。 模块 >>> import math >>> math.sin(0) 0.0 模块是程序 任何python程序都可以作...
  • signjing
  • signjing
  • 2014年06月20日 16:17
  • 1342

Python 更加抽象

更加抽象 前几章介绍了Python主要内建对象类型(数字、字符串、列表、元组和字典),以及内建函数和标准库的用法,还有定义函数的方法。现在看来还差一点——创建自己的对象。为什么要自定义对象呢?创建自己...
  • qq_35175481
  • qq_35175481
  • 2016年10月07日 10:41
  • 349

《Python基础教程》学习笔记 Chp6 抽象

创建函数 函数是可以调用的(可能带有参数,也就是放在圆括号中的值),它执行某种行为并且返回一个值。一般来说,内建的callable函数可以用来判断函数是否可调用: i...
  • lzh398651363
  • lzh398651363
  • 2016年05月31日 14:33
  • 370

《Python基础教程》学习笔记(6-7抽象)

6. 抽象6.1 函数使用def定义函数def fibs(num): result = [0, 1] for i in range(num - 2): result.a...
  • u013980127
  • u013980127
  • 2016年10月30日 21:38
  • 178

python基础教程_学习笔记9:抽象

抽象 懒惰即美德。 抽象和结构 抽象可以节省大量工作,实际上它的作用还要更大,它是使得计算机程序可以让人读懂的关键。 创建函数 函数可以调用(可能包含参数,也就是放在圆括号中的值),它执行某...
  • signjing
  • signjing
  • 2014年06月14日 15:11
  • 1289

Python基础教程第六章学习笔记——抽象

6 抽象 介绍如何将语句组织成函数,告诉计算机如何做事(只告诉一次就可以) 还会介绍参数(parameter)和作用域(scope)概念 递归的概念及在程序中的用途 6.1 懒惰即美德 一段代码可能要...
  • youngersteral
  • youngersteral
  • 2017年09月14日 12:56
  • 175
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《Python基础教程》学习笔记 Chp7 更加抽象
举报原因:
原因补充:

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