Comme une autre approche du système de plugins, vous pouvez vérifier le projet Extend Me .
Par exemple, définissons une classe simple et son extension
# 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)
Et essayez de l'utiliser:
>>> 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
Et montrez ce qui se cache derrière la scène:
>>> my_cool_obj.__class__.__bases__
[MyCoolClassExtension1, MyCoolClass]
La bibliothèque extend_me manipule le processus de création de classe via des métaclasses, ainsi dans l'exemple ci-dessus, lors de la création d'une nouvelle instance de, MyCoolClass
nous avons une instance de nouvelle classe qui est une sous-classe des deux MyCoolClassExtension
et qui MyCoolClass
possède la fonctionnalité des deux, grâce à l' héritage multiple de Python
Pour un meilleur contrôle sur la création de classe, il y a quelques métaclasses définies dans cette bibliothèque:
ExtensibleType
- permet une extensibilité simple par sous-classement
ExtensibleByHashType
- similaire à ExtensibleType, mais ayant la capacité de créer des versions spécialisées de la classe, permettant l'extension globale de la classe de base et l'extension des versions spécialisées de la classe
Cette bibliothèque est utilisée dans OpenERP Proxy Project , et semble fonctionner assez bien!
Pour un exemple réel d'utilisation, regardez dans l'extension 'field_datetime' d'OpenERP Proxy :
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
Record
voici un objet extensible. RecordDateTime
est l'extension.
Pour activer l'extension, importez simplement le module contenant la classe d'extension et (dans le cas ci-dessus) Record
objets créés après avoir une classe d'extension dans les classes de base, ayant ainsi toutes ses fonctionnalités.
Le principal avantage de cette bibliothèque est que le code qui exploite des objets extensibles n'a pas besoin de connaître l'extension et les extensions pourraient tout changer dans les objets extensibles.