On 5/12/07, Jeff Shell <[EMAIL PROTECTED]> wrote: > I like that the interface hierarchy is different than an > implementation hierarchy. I like that it's easier to test for > interface provision than it is to use isinstance() - > `IFoo.providedBy(obj)` often works regardless of whether 'obj' is a > proxy or wrapper, and without tampering with `isinstance()`. I know > that there's been talk of having ``__isinstance()__`` and > ``__issubclass()__``, which could be used to take care of the > proxy/wrapper problem. But I haven't formed an opinion about how I > feel about that. > > I like the Roles/Traits side of zope.interface because I can declare > that information about third party products. For example, I was able > to add some 'implements' directives to a SQLAlchemy 'InstrumentedList' > class - basically I said that it supported the common `ISequence` > interface. Which I recognize that in this particular scenario, if that > role/trait or abstract base class was built in, than I wouldn't have > had to do that (since it is based on a common Python type spec). Still > though - it doesn't matter whether `InstrumentedList` derives from > `list` or `UserList` or implements the entire sequence API directly. > The Trait could be assigned independent of implementation, and could > be done in another product without affecting any internals of > SQLAlchemy: I didn't have to make a subclass that SQLAlchemy wouldn't > know to instantiate. I didn't have to write an adapter. I just had to > say "I happen to know that instances of this class will have this > trait". > > I don't know if that's LBYL, EYV (Eat Your Vegetables), LBWBCTS (Look > Both Ways Before Crossing The Street), or what. I think it's just a > way of saying "I happen to know that this thing smells like a duck. It > doesn't say that it smells like a duck, but I know it smells like a > duck. And for everywhere that I expect to find the fine fragrance of > duck, this thing should be allowed." No adapters, no changing the base > classes, no meddling with method resolution order, just adding a > trait. The trait in this case is like an access pass - just an extra > thing worn around the neck that will grant you access to certain doors > and pathways. It doesn't change who you are or how you accomplish your > job.
Please have a look at the latest version (updated yesterday) of PEP 3119. Using the classes there, you can say from collections import Sequence Sequence.register(InstrumentedList) >From this point, issubclass(InstrumentedList, Sequence) will be true (and likewise for instances of it and isinstance(x, Sequence)). But InstrumentedList's __mro__ and __bases__ are unchanged. This is pretty close to what you expect from a Zope interface, except you can also subclass Sequence if you want to, and a later version of SQLAlchemy could subclass InstrumentedList from Sequence. (The register() call would then be redundant, but you won't have to remove it -- it will act as a no-op if the given subclass relationship already holds.) A subclass of Sequence can behave either as an implementation class (when it provides implementations of all required methods) or as another interface (if it adds one or more new abstract method). You can think of Sequence and its brethren as mix-ins -- they provide some default implementations of certain methods, and abstract definitions of others (the "essential" ones; e.g. Sequence makes __len__ and __getitem__ abstract but __iter__ has a concrete default implementation). Phillip has told me that this is transparent to his GF machinery -- if you overload a GF on Sequence, and InstrumentedList is a subclass Sequence (whether through registration or subclassing), then that version of the GF will be used for InstrumentedList (unless there's a more specific overloaded version of course). -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com