python都有哪些包装_Python基础:21包装

本文深入探讨了Python中的包装技术,包括其概念、作用以及如何通过__getattr__()方法实现授权。通过包装,可以对已有对象进行功能增强或修改,隐藏不希望暴露的行为。文中提供了包装复数、列表和文件对象的示例,展示了如何定制对象的行为,如复数属性的访问、列表方法的授权以及文件对象的写入过滤。包装技术在Python中对于对象行为的控制和接口设计具有重要意义。
摘要由CSDN通过智能技术生成

“包装”在Python 编程中经常会被提到的一个术语。意思是对一个已存在的对象进行包装,可以是对一个已存在的对象,增加,删除,或者修改功能。

可以包装任何类型(type)作为一个类(class)的核心成员,以使新对象的行为模仿你想要的数据类型中已存在的行为,并且去掉你不希望存在的行为。

授权是包装的一个特性,实现授权的关键点就是覆盖__getattr__()方法,在其中包含一个对getattr()内建函数的调用。

特殊方法__getattr__()的工作方式是,当搜索一个属性时,任何局部对象首先被找到(定制的对象)。如果搜索失败了,则__getattr__()会被调用。

换言之,当引用一个属性时,Python 解释器将试着在局部名称空间中查找那个名字,如果没有在局部字典中找到,则搜索类名称空间,最后,如果两类搜索都失败了,搜索则对原对象开始授权请求,此时,__getattr__()会被调用。

包装的一个简单例子:

classWrapMe(object):def __init__(self, obj):

self.__data =objdefget(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)

这里将用到复数,因为所有Python数值类型,只有复数拥有属性:

>>> wrapcomplex =WrapMe(3.5+4.2j)>>>wrapcomplex

(3.5+4.2j)>>>wrapcomplex.real3.5

>>>wrapcomplex.imag4.2

>>>wrapcomplex.conjugate()

(3.5-4.2j)>>>wrapcomplex.get()

(3.5+4.2j)

访问复数的三种属性,我们的自定义类中一种都没有定义,对这些属性的访问,是通过getattr()方法,授权给对象。调用get()方法没有授权,因为它是为我们的对象定义的。

下一个使用包装类的例子用到一个列表。我们将会创建对象,然后执行多种操作,每次授权给列表方法。

>>> wraplist =WrapMe([123, 'foo', 45.67])>>>wraplist.append('bar')>>>wraplist.append(123)>>>wraplist

[123, 'foo', 45.67, 'bar',123]>>>wraplist.index(45.67)2

>>>wraplist.count(123)2

>>>wraplist.pop()123

>>>wraplist

[123, 'foo', 45.67, 'bar']

注意,只有已存在的属性是在此代码中授权的。特殊行为没有在类型的方法列表中,不能被访问,因为它们不是属性。一个例子是,对列表的切片操作,它是内建于类型中的,而不是像append()方法那样作为属性存在的。也就是说,切片操作符是序列类型的一部分,并不是通过__getitem__()特殊方法来实现的。

>>> wraplist[2]

Traceback (most recent calllast):

File"", line 1, inTypeError:'WrapMe' objectdoes not support indexing

然而,还有一种"作弊"的方法,访问实际对象[通过get()方法]和它的切片能力.

>>> reallist =wraplist.get()>>> reallist[3]'bar'

这就是为什么需要实现get()方法了----仅仅是为了我们需要取得对原对象进行访问这种情况。

另外一个例子,描述了一个包装文件对象的类。我们的类与一般的文件对象行为完全一样, 除了在写模式中,字符串只有全部为大写时,才写入文件。下面提供一个文件类对象,定制write()方法,同时,给文件对象授权其它的功能:

classCapOpen(object):def __init__(self, fn,mode='r', buf=-1):

self.file=open(fn, mode, buf)def __str__(self):returnstr(self.file)def __repr__(self):return`self.file`defwrite(self, line):

self.file.write(line.upper())def __getattr__(self, attr):returngetattr(self.file, attr)>>> f = CapOpen('/tmp/xxx','w')>>>f.write('delegation example\n')>>>f.write('faye is good\n')>>>f.write('at delegating\n')>>>f.close()>>>f

可以看到,唯一不同的是第一次对CapOpen()的调用,而不是open()。除了write(),所有属性都已授权给文件对象:

>>> f =CapOpen('/tmp/xxx', 'r')>>> for eachLine inf:

...printeachLine,

...

DELEGATION EXAMPLE

FAYE IS GOOD

AT DELEGATING

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值