DRY and static attribute for multiple classes.

Marc Aymerich glicerinu at gmail.com
Wed Feb 2 21:32:44 CET 2011


On Feb 2, 5:58 pm, Michele Simionato <michele.simion... at gmail.com>
wrote:
> Notice that Peter's approach also works without inheritance:
>
> registries = {}
>
> @property
> def per_class(self):
>    cls = type(self)
>    try:
>       return registries[cls]
>    except KeyError:
>       result = registries[cls] = []
>       return result
>
> class A(object): per_class=per_class
> class B(object): per_class=per_class
> assert A().per_class is A().per_class
> assert B().per_class is B().per_class
> assert A().per_class is not B().per_class
>
> (you can also put the per_class property in a module and import it
> with
> class A(object): from module import per_class).
>
> There is no need to use inheritance if you only need one method.
> Notice also that if you
> are working with a complex third party framework (say Django) that may
> use metaclasses
> or strange tricks (such as __slots__) the safer way is to avoid both
> inheritance and metaclasses.
> HTH,
>
>  Michele

Hi Michele, thanks for your contributions. Actually the Petter
proposal it's working for me (AFAIK). I think because my base class is
an abstract class. In particular my adaptation of his proposal (with
the rest of the current BaseService class) is:


from django.db import models
from django.contrib.contenttypes import generic
class BaseService(models.Model):

    class Meta:
        abstract = True

    _service_registry = []
    _plugin_registry = {}

    @classmethod
    def plugin_register(cls, str):
        # Per subclass register
        try: cls._plugin_registry[cls].append(str)
        except KeyError: cls._plugin_registry[cls] = []

    @classmethod
    def get_plugin_registred(cls):
        # Per subclass register
        try:
            return cls._plugin_registry[cls]
        except KeyError:
            result = cls._plugin_registry[cls] = []
            return result

    @property
    def extentions_attributes(self):
        attributes = []
        for model in _plugin_registry:
            for attribute in model.get_attributes(self):
                attributes.append(attribute[0])
        return attributes

    @classmethod
    def service_register(cls):
	    cls._service_registry.append(cls)

    @classmethod
    def get_service_registred(cls):
        return cls._service_registry

    @property
    def attributes(self):
        return []


IMHO Django handles very well inheritance, and subclassing is their
major method in order to use the framework. I completely agree with
metaclasses should be avoided when you're working with frameworks :)

BTW, is there any alternative to the inheritance pattern in order to
provide this set of methods for multiple classes? I'm pretty new in
OOP :)

Thanks!



More information about the Python-list mailing list