可爱的 Python: Python 之优雅与瑕疵,第 2 部分
2008-09-30 12:58:25 来源:WEB开发网Foo 类将 this 和 that 定义为 ErrWriter 类的描述符。属性 other 只是一个普通的类属性。在第一次访问 foo.other 时,我们将读取类属性;对其赋值后,将读取实例属性。类属性仍然存在,只是被隐藏了,例如:
清单 7. 类属性与实例属性的对比
>>> foo.other
6
>>> foo.__class__.other
4
相比之下,即使可以通过实例进行访问,描述符仍然属于类级别对象。这通常对描述符起到不好的影响,使它类似于一个单例模式(singleton)。例如:
清单 8. 单例模式描述符
>>> foo2 = Foo()
>>> foo2.this
get <__main__.ErrWriter object at 0x5cec90>
<__main__.Foo object at 0x5cebf0> <class '__main__.Foo'>
5
要模拟普通的 “单实例” 行为,需要利用传递到 ErrWriter 方法中的 obj。obj 是具有描述符的实例。因此您可能会定义一个非单例模式的描述符,例如:
清单 9. 定义一个非单例模式的描述符
class ErrWriter(object):
def __init__(self):
self.inst = {}
def __get__(self, obj, type=None):
return self.inst[obj]
def __set__(self, obj, value):
self.inst[obj] = value
def __delete__(self, obj):
del self.inst[obj]
特性
特性的工作原理与描述符类似,但通常是在特定类的内部定义,而不是被创建为各种类都可使用的 “实用描述符”。与 “常规” 描述符一样,特性的工作原理就是定义 “getters”、“setters” 和 “deleters”。之后,使用特殊函数 property() 将这些方法转换为一种描述符。对于希望进一步了解这些内容的读者:property() 并不是一个真正的函数,而是一种类型 —— 因此不必过多考虑它。
更多精彩
赞助商链接