作为插件系统的另一种方法,你可以检查Extend Me项目。
例如,让我们定义一个简单的类及其扩展
# Define base class for extensions (mount point)
class MyCoolClass(Extensible):
my_attr_1 = 25
def my_method1(self, arg1):
print('Hello, %s' % arg1)
# Define extension, which implements some aditional logic
# or modifies existing logic of base class (MyCoolClass)
# Also any extension class maby be placed in any module You like,
# It just needs to be imported at start of app
class MyCoolClassExtension1(MyCoolClass):
def my_method1(self, arg1):
super(MyCoolClassExtension1, self).my_method1(arg1.upper())
def my_method2(self, arg1):
print("Good by, %s" % arg1)
试着使用它:
>>> my_cool_obj = MyCoolClass()
>>> print(my_cool_obj.my_attr_1)
25
>>> my_cool_obj.my_method1('World')
Hello, WORLD
>>> my_cool_obj.my_method2('World')
Good by, World
并展示隐藏在幕后的东西:
>>> my_cool_obj.__class__.__bases__
[MyCoolClassExtension1, MyCoolClass]
extend_me库通过元类来操作类的创建过程,因此在上面的例子中,当创建MyCoolClass的新实例时,我们得到了一个新类的实例,它是MyCoolClassExtension和MyCoolClass的子类,由于Python的多重继承,它具有两者的功能
为了更好地控制类的创建,在这个库中定义了一些元类:
ExtensibleType—通过子类化允许简单的扩展性
ExtensibleByHashType -类似ExtensibleType,但有能力
构建类的专门版本,允许全局扩展
基类和类的专门版本扩展的
这个库是在OpenERP代理项目中使用的,似乎工作得很好!
对于实际使用的例子,看看OpenERP代理的“field_datetime”扩展:
from ..orm.record import Record
import datetime
class RecordDateTime(Record):
""" Provides auto conversion of datetime fields from
string got from server to comparable datetime objects
"""
def _get_field(self, ftype, name):
res = super(RecordDateTime, self)._get_field(ftype, name)
if res and ftype == 'date':
return datetime.datetime.strptime(res, '%Y-%m-%d').date()
elif res and ftype == 'datetime':
return datetime.datetime.strptime(res, '%Y-%m-%d %H:%M:%S')
return res
这里记录的是可执行对象。RecordDateTime是扩展名。
要启用扩展,只需导入包含扩展类的模块,并且(在上述情况下)在它之后创建的所有Record对象将在基类中具有扩展类,从而具有其所有功能。
这个库的主要优点是,操作可扩展对象的代码不需要了解扩展,而扩展可以改变可扩展对象中的所有内容。