学过 Python 教程,我们知道,对象的属性可以使用 del 语句删除:
del my_object.an_attribute
其实,使用 Python 编程时不常删除属性,通过特性删除属性更少见。但是,Python 支持这么做,我可以虚构一个示例,演示这种处理方式。
定义特性时,可以使用 @my_propety.deleter 装饰器包装一个方法,负责删除特性管理的属性。下面兑现承诺,虚构一个示例,说明如何定义特性删值方法,如示例 19-26 所示。
示例 19-26 blackknight.py:灵感来自电影《巨蟒与圣杯》中的黑衣骑士角色
class BlackKnight:
def __init__(self):
self.members = ['an arm', 'another arm',
'a leg', 'another leg']
self.phrases = ["'Tis but a scratch.",
"It's just a flesh wound.",
"I'm invincible!",
"All right, we'll call it a draw."]
@property
def member(self):
print('next member is:')
return self.members[0]
@member.deleter
def member(self):
text = 'BLACK KNIGHT (loses {})\n-- {}'
print(text.format(self.members.pop(0), self.phrases.pop(0)))
blackknight.py 脚本的 doctest 在示例 19-27 中。
示例 19-27 blackknight.py:示例 19-26 的 doctest(黑衣骑士从不屈服)
>>> knight = BlackKnight() >>> knight.member next member is: 'an arm' >>> del knight.member BLACK KNIGHT (loses an arm) -- 'Tis but a scratch. >>> del knight.member BLACK KNIGHT (loses another arm) -- It's just a flesh wound. >>> del knight.member BLACK KNIGHT (loses a leg) -- I'm invincible! >>> del knight.member BLACK KNIGHT (loses another leg) -- All right, we'll call it a draw.
在不使用装饰器的经典调用句法中,fdel 参数用于设置删值函数。例如,在 BlackKnight 类的定义体中可以像下面这样创建 member 特性:
member = property(member_getter, fdel=member_deleter)
如果不使用特性,还可以实现低层特殊的 __delattr__ 方法处理删除属性的操作,参见 19.6.3 节。留给喜欢拖延的读者一个练习:虚构一个类,定义 __delattr__ 方法。
特性是个强大的功能,不过有时更适合使用简单的或底层的替代方案。在本章的最后一节中,我们将回顾 Python 为动态属性编程提供的部分核心 API。