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

[Python]面向对象编程之代理(Delegation)

2014-07-21 15:47 155 查看
"Wrapping"在Python编程中是一个常见术语。它是一个通用的名字,意思是对一个已存在的的对象进行封装,不管他是数据类型还是一段代码,可以是对一个已经存在的对象增加新的、删除不要的或修改其他已经存在的功能。

“Delegation”是“Wrapping”的一个特性,可用于简化处理相关命令性的功能,最大化重用已有代码。

实现“Delegation”的关键点在于覆盖__getattr__()方法,在代码中包含一个对内建函数getattr()的调用。特殊方法__getattr__()的工作方式是,当搜索一个属性时,任何局部对象首先被找到(定制的对象)。如果搜索失败了,则__getattr__()会被调用,然后调用getattr()得到一个对象的默认行为。

例一(简单的“Wrap”封装任何类型的对象):

class WrapMe(object):
def __init__(self,obj):
self.__data = obj

def get(self):
return self.__data

def __repr__(self):
return 'self.__data'

def __str__(self):
return str(self.__data)

def __getattr__(self,attr):
return getattr(self.__data,attr)

wrapedcomplex = WrapMe(3.5+4.2j)
print wrapedcomplex
print wrapedcomplex.real
print wrapedcomplex.imag
print wrapedcomplex.conjugate()
print wrapedcomplex.get()
print "--------------------------*---------------------------"
wrapedlist = WrapMe([123,"foo",43.29])
wrapedlist.append("bar")
wrapedlist.append(123)
print wrapedlist
print wrapedlist.index(43.29)
print wrapedlist.count(123)
print wrapedlist.pop()
print wrapedlist
(3.5+4.2j)

3.5

4.2

(3.5-4.2j)

(3.5+4.2j)

--------------------------*---------------------------

[123, 'foo', 43.29, 'bar', 123]

2

2

123

[123, 'foo', 43.29, 'bar']

例二(加入时间顺序数据):

from time  import time, ctime, sleep

class TimedWrapMe(object):
def __init__(self,obj):
self.__data = obj
self.__ctime = self.__mtime = \
self.__atime = time()

def get(self):
self.__atime = time()
return self.__data

def gettimeval(self,t_type):
if not isinstance(t_type,str) or \
t_type[0] not in "cma":
return TypeError,\
"argument of 'c','m' or 'a' req"
attrstr = "_%s__%stime"% \
(self.__class__.__name__,t_type[0])
return getattr(self,attrstr)

def gettimestr(self,t_type):
return ctime(self.gettimeval(t_type))

def set(self,obj):
self.__data = obj
self.__atime = self.__atime = time()

def __repr__(self):
self.__atime = time()
return 'self.__data'

def __str__(self):
self.__atime = time()
return str(self.__data)

def __getattr__(self,attr):
self.__atime = time()
return getattr(self.__data,attr)

timeWrappedObj = TimedWrapMe(932)
print timeWrappedObj.gettimestr('c')
print timeWrappedObj.gettimestr('m')
print timeWrappedObj.gettimestr('a')
sleep(2)
print timeWrappedObj
print timeWrappedObj.gettimestr('c')
print timeWrappedObj.gettimestr('m')
print timeWrappedObj.gettimestr('a')


Mon Jul 21 14:55:10 2014

Mon Jul 21 14:55:10 2014

Mon Jul 21 14:55:10 2014

932

Mon Jul 21 14:55:10 2014

Mon Jul 21 14:55:10 2014

Mon Jul 21 14:55:12 2014

注意:__attr属性在命名mangling后会变成_ClassName__attr这样的形式,所以在getattr()调用中,使用_ClassName__attr这样的参数。

例三(文件读写的简单定制):

class CapOpen(object):
def __init__(self,fn,mode='r',buf=-1):
self.file = open(fn,mode,buf)

def __str__(self):
return str(self.file)

def __repr__(self):
return 'self.file'

def write(self,line):
self.file.write(line.upper())

def __getattr__(self,attr):
return getattr(self.file,attr)


REF:Core Python Programming
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: