可爱的 Python: Python 之优雅与瑕疵,第 2 部分
2008-09-30 12:58:25 来源:WEB开发网然而,很多时候,您仅希望以某种特殊的方式使用少数属性,而其他属性则按照普通属性操作。这些普通属性不会触发任何特殊代码,也不会因为遍历方法代码而浪费时间。在这些情况下,您可以对属性使用描述符。或者,定义与描述符密切关联的特性(property)。实际上,特性和描述符基本是同一类东西,但是定义语法却截然不同。并且由于定义类型存在差别,正如您所料,特性和描述符各有优缺点。
让我们首先查看描述符。其原理就是将某种特殊类型的类的实例指派给另一个类的属性。这个特殊的 “描述符” 类是一种新式类,包含的方法有 .__get__()、.__set__() 和 __delete__()(或者至少包含其中的几种)。如果描述符类至少实现了前两个方法,则被称为 “数据描述符”;如果只实现了第一个方法,则被称为 “非数据描述符”。
非数据描述符最常用于返回一个可调用对象。某种意义上讲,非数据描述符通常是某种方法的一个好听的名字 —— 但是可以在运行时确定描述符访问所返回的特定方法。它将首先处理类似元类和修饰器等最棘手的内容,我在之前的文章中讨论过这些内容(参考 参考资料 中的链接)。当然,普通的方法也可以根据运行时条件确定要运行哪些代码,因此,关于在运行时确定 “方法” 处理的概念不存在什么特别新的内容。
无论如何,数据描述符更为常见,因此我将向您展示一个例子。这种描述符可以 返回可调用的内容 —— 毕竟 Python 函数或方法可以返回任何内容。但此处的示例仅处理简单的值(和副作用)。我们希望利用一些属性将动作记录到 STDERR:
清单 6. 数据描述符示例
>>> class ErrWriter(object):
... def __get__(self, obj, type=None):
... print >> sys.stderr, "get", self, obj, type
... return self.data
... def __set__(self, obj, value):
... print >> sys.stderr, "set", self, obj, value
... self.data = value
... def __delete__(self, obj):
... print >> sys.stderr, "delete", self, obj
... del self.data
>>> class Foo(object):
... this = ErrWriter()
... that = ErrWriter()
... other = 4
>>> foo = Foo()
>>> foo.this = 5
set <__main__.ErrWriter object at 0x5cec90>
<__main__.Foo object at 0x5cebf0> 5
>>> print foo.this
get <__main__.ErrWriter object at 0x5cec90>
<__main__.Foo object at 0x5cebf0> <class '__main__.Foo'>
5
>>> print foo.other
4
>>> foo.other = 6
>>> print foo.other
6
更多精彩
赞助商链接