On Sun, 13 Mar 2011 15:01:53 -0400, Darren Dale <[email protected]> wrote: > I've been learning about python's abstract base classes at > http://www.python.org/dev/peps/pep-3119/ and > http://docs.python.org/py3k/library/abc.html . The PEP mentions that > there is considerable overlap between ABCs and interfaces, and I'm > rereading the dip documentation on interfaces now. If I understand > correctly, dip's "implements" decorator is similar (perhaps based on) > python's abstract base class "register" class method. Is it ever the > case that dip classes actually subclass a dip interface, as python > classes would subclass one or more abstract base class?
No (as in it's technically possible but you shouldn't do it). dip interfaces can be sub-classed to created more specific interfaces, but the only link to an implementation of the interface should be via the @implements or @adapt class decorators. dip does support the ABC hooks that means that issubclass() and isinstance() can be used between an object that implements an interface and the interface itself. It comes down to a personal philosophical choice - I much prefer interfaces to ABCs. The problem with ABCs is that they encourage putting the interface definition in the same place as a default implementation. >From an architectural point of view I strongly believe that they should be kept separate. Interfaces have their own problems of course - mainly the need to repeat the interface definition in an implementation. With Traits, for example, an implementation must contain a copy of the interface's attributes and methods - which is error prone. dip is better because you don't have to repeat the definition of the interface's attributes - they are injected automatically into the implementation - but you still (for the moment anyway) to have to repeat the interface's methods. > Also, this morning I suggested on python-ideas a small tweak to > python's builtin "property" which would allow an abstract properties > to be declared using the decorator syntax. I thought it might be of > interest to dip: > > import abc > > class Property(property): > > def __init__(self, *args, **kwargs): > super(Property, self).__init__(*args, **kwargs) > if (getattr(self.fget, '__isabstractmethod__', False) or > getattr(self.fset, '__isabstractmethod__', False) or > getattr(self.fdel, '__isabstractmethod__', False)): > self.__isabstractmethod__ = True > > class C(metaclass=abc.ABCMeta): > @Property > @abc.abstractmethod > def x(self): > return 1 > @x.setter > @abc.abstractmethod > def x(self, val): > pass > > try: > # Can't instantiate C, C.x getter and setter are abstract > c=C() > except TypeError as e: > print(e) > > class D(C): > @C.x.getter > def x(self): > return 2 > > try: > # Can't instantiate D, the D.x setter is still abstract > d=D() > except TypeError as e: > print(e) > > class E(D): > @D.x.setter > def x(self, val): > pass > > # E is now instantiable > print(E()) The way I would do this in dip would, instead of automatically injecting any missing interface methods (which are all abstract by definition), I would simply raise an exception. This would also address the point you made in your second email. Phil _______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
