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

第五章 对象和面向对象

2013-06-15 16:06 141 查看
第五章 对象和面向对象
1、使用 from module import 导入模块
1)import module
2)from module import
直接导入到局部名字空间,所以它可以直接使用,而不需要加上模块名的限定
适用情况:
①如果你要经常访问模块的属性和方法,且不想一遍又一遍地敲入模块名,使用 from module import。
②如果你想要有选择地导入某些属性和方法,而不想要其它的,使用 from module import。
③如果模块包含的属性和方法与你的某个模块同名,你必须使用 import module 来避免名字冲突

2、类的定义
1)例子
from UserDict import UserDict
class FileInfo(UserDict):     #类的基类只是简单地列在类名后面的小括号里;多重继承可以列出许多你想要的类名,以逗号分隔
"store file metadata"
def __init__(self, filename=None):     # self ,每个类方法的第一个参数,都是指向类的当前实例的引用
UserDict.__init__(self)     #必须显示地调用在父类中的合适方法
self["name"] = filename

2)了解何时去使用 self 和 __init__

①__init__ 在类的实例创建后被立即调用。对象在调用时已经被构造出来了,已经有了一个对类的新实例的有效引用
②在 __init__ 方法中,self 指向新创建的对象;在其它的类方法中,它指向方法被调用的类实例
③注意 __init__ 方法从不返回一个值

④当定义你自已的类方法时,你必须 明确将 self 作为每个方法的第一个参数列出,包括 __init__。
⑤当从你的类中调用一个父类的一个方法时,你必须包括 self 参数。
⑥但当你从类的外部调用你的类方法时,你不必对 self 参数指定任何值;你完全将其忽略,而 Python 会自动地替你增加实例的引用。
⑦__init__ 方法是可选的,但是一旦你定义了,就必须记得显示调用父类的 __init__ 方法

3、类的实例化
只要调用类 (就好像它是一个函数),传入定义在 __init__ 方法中的参数。返回值将是新创建的对象
1)创建 FileInfo 实例
>>> import fileinfo
>>> f = fileinfo.FileInfo("/music/_singles/kairo.mp3")     #创建 FileInfo 类 (定义在 fileinfo 模块中) 的实例,并且将新创建的实例赋值给变量 f
>>> f
{'name': '/music/_singles/kairo.mp3'}     #创建类实例时你传入的参数被正确发送到 __init__ 方法中

2)垃圾回收
不需要明确地释放实例,因为当指派给它们的变量超出作用域时,它们会被自动地释放

4、探索 UserDict:一个封装类
1)定义 UserDict 类
class UserDict:
def __init__(self, dict=None):
self.data = {}     #数据属性:由某个特定的类实例所拥有的数据
if dict is not None: self.update(dict)     # update 看作是合并函数,而不是复制函数

数据属性:要从类外的代码引用这个属性,需要用实例的名字限定它,instance.data。要在类的内部引用一个数据属性,我们使用 self 作为限定符

5、专用方法
提供了一种方法,可以将非方法调用语法映射到方法调用上
1)__getitem__ 专用方法
def __getitem__(self, key): return self.data[key]

>>> f.__getitem__("name")
'/music/_singles/kairo.mp3'
>>> f["name"]     #Python 已经将这个语法转化为 f.__getitem__("name") 的方法调用
'/music/_singles/kairo.mp3'

2)__setitem__ 专用方法
def __setitem__(self, key, item): self.data[key] = item

>>> f.__setitem__("genre", 31)
>>> f
{'name':'/music/_singles/kairo.mp3', 'genre':31}
>>> f["genre"] = 32
>>> f
{'name':'/music/_singles/kairo.mp3', 'genre':32}


6、高级专用类方法
1)UserDict 中更多的专用方法:
def __repr__(self): return repr(self.data)     #返回一个对象的字符串表示
def __cmp__(self, dict):     #比较类实例
if isinstance(dict, UserDict):
return cmp(self.data, dict.data)
else:
return cmp(self.data, dict)
def __len__(self): return len(self.data)     #返回一个对象的长度
def __delitem__(self, key): del self.data[key]     #删除

2)同一性
对象同一性:通过使用 str1 == str2 可以确定两个字符串变量是否指向同一块物理内存位置,在 Python 中写为 str1 is str2,比较值使用 str1 == str2

7、类属性
1)类属性介绍
类属性是由类本身所拥有的
数据属性是被一个特定的类实例所拥有的变量
class MP3FileInfo(FileInfo):
"store ID3v1.0 MP3 tags"
tagDataMap = {"title"   : (  3,  33, stripnulls),
"artist"  : ( 33,  63, stripnulls),
"album"   : ( 63,  93, stripnulls),
"year"    : ( 93,  97, stripnulls),
"comment" : ( 97, 126, stripnulls),
"genre"   : (127, 128, ord)}

>>> fileinfo.MP3FileInfo.tagDataMap
{'title': (3, 33, <function stripnulls at 0260C8D4>),
'genre': (127, 128, <built-in function ord>),
'artist': (33, 63, <function stripnulls at 0260C8D4>),
'year': (93, 97, <function stripnulls at 0260C8D4>),
'comment': (97, 126, <function stripnulls at 0260C8D4>),
'album': (63, 93, <function stripnulls at 0260C8D4>)}

①类属性既可以通过直接对类的引用,也可以通过对类的任意实例的引用来使用
②类属性可以定义在这里,数据属性定义在 __init__ 方法中
2)修改类属性
>>> class counter:
...     count = 0
...     def __init__(self):
...         self.__class__.count += 1
>>> c = counter()
>>> c.count
1

①__class__ 是每个类实例的一个内置属性 (也是每个类的)。它是一个类的引用
②创建一个类实例会调用 __init__ 方法,它会给类属性 count 加 1。这样会影响到类自身,不只是新创建的实例

8、私有函数
1)私有概念

私有函数不可以从它们的模块外面被调用
私有类方法不能够从它们的类外面被调用
私有属性不能够从它们的类外面被访问

2)一个 Python 函数,方法,或属性是私有还是公有,完全取决于它的名字
如果一个 Python 函数,类方法,或属性的名字以两个下划线开始 (但不是结束),它是私有的;其它所有的都是公有的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python