Python 中的元类编程(3)
2008-09-30 12:42:40 来源:WEB开发网另一点需要注意的是,Enhance() 函数的功能远不只上面提到的简单版本。装饰器更擅长完成复杂的增强功能。例如,以下是一个将 “记录” 添加到类的 Enhance() 函数:
清单 13. 类增强的变体
@classinitializer
def def_properties(cls, schema):
"""
Add properties to cls, according to the schema, which is a list
of pairs (fieldname, typecast). A typecast is a
callable converting the field value into a Python type.
The initializer saves the attribute names in a list cls.fields
and the typecasts in a list cls.types. Instances of cls are expected
to have private attributes with names determined by the field names.
"""
cls.fields = []
cls.types = []
for name, typecast in schema:
if hasattr(cls, name): # avoid accidental overriding
raise AttributeError('You are overriding %s!' % name)
def getter(self, name=name):
return getattr(self, '_' + name)
def setter(self, value, name=name, typecast=typecast):
setattr(self, '_' + name, typecast(value))
setattr(cls, name, property(getter, setter))
cls.fields.append(name)
cls.types.append(typecast)
不同之处在于:(a)什么被增强了;(b)这种方法是如何工作的;(c)基类的工作都保持正交:
清单 14. 自定义记录类
>>> class Article(object):
... # fields and types are dynamically set by the initializer
... def_properties([('title', str), ('author', str), ('date', date)])
... def __init__(self, values): # add error checking if you like
... for field, cast, value in zip(self.fields, self.types, values):
... setattr(self, '_' + field, cast(value))
>>> a=Article(['How to use class initializers', 'M. Simionato', '2006-07-10'])
>>> a.title
'How to use class initializers'
>>> a.author
'M. Simionato'
>>> a.date
datetime.date(2006, 7, 10)
更多精彩
赞助商链接