[Python-Dev] very revised proposal for interfaces (original) (raw)
John Williams jrw@pobox.com
Wed, 02 Oct 2002 02:10:22 -0500
- Previous message: [Python-Dev] Urgent: regex Perl vs Python
- Next message: [Python-Dev] Re: *very* revised proposal for interfaces
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
After re-reading PEPs 245 (interface syntax) and 246 (object adaptation), I hit on a new idea that seems to do everything these two PEPs and my original proposal (plus revisions) do, all with much less fuss. I also realized I was adding a lot of excess complexity in order to implement all the rigorous error checking that doesn't really make sense in the Python world anyway (thanks for nudging me in that direction!) As a side effect it's also a lot easier to explain.
Here's the new version, in a no-frills stripped-down form, explained by example.
Create an interface--not much new here, just simpler syntax and fewer
frills. class I(interface): prop1 = "Docstring for property prop1."
It would be good form to put an argument list here,
but this method will never be called so it's not necessary.
def meth1(): "Docstring for method meth1."
Create a class implementing the interfac.
It inherits from "object" explicitly, since a class whose bases
are all interfaces is itself an interface, not an implementation.
class C(object, I): def meth(self,a,b): print "This is I.meth1 implemented by C."
(I'm not quite sure how to handle properies yet.)
assert I not in C.bases # Interfaces are not really base classes!
Example method requiring an object supporting interface I.
def usingI(x,y):
Check that x supports interface I. Return either x or a suitable
wrapper around x that supports I's methods. If x doesn't support I,
raise an exception.
x = I(x)
Check that y also supports I. If it doesn't, return None instead of
raising an exception.
y = I(y, None) ...
Example of binding an existing class to an interface. Like creating
an ordinary implementation, the bases are an interface and a regular
class, but instead of creating a usable new class, it just associates
an interface with a class and defines how the interface's methods are
implmented. The magic class name binding triggers this behavior.
Instances of this wrapper class are created by calling interface I.
class binding(str, I): def meth1(self,a,b): # Say what meth1 does on strings. assert isinstance(self, str) print "I.meth1 called on", self
Example of using binding to resolve a conflict between two interfaces.
class J(interface): def meth1(): "No relation to I.meth1!" class D(object, I, J): # Implement two interfaces.
Define both I.meth1 and J.meth1 for this class.
def meth1(self,a,b): print "This is I.meth1 implemented by D." class binding(D,J): def meth1(self): print "This is J.meth1 implemented by D."
Now to call these two methods, we can do this:
d = D() i = I(d) # Note i could really just be d here, not that it matters. i.meth1(1,2) # Prints "This is I.meth1 implemented by D." j = J(d) # Here j must be a wrapper to make things work right. j.meth1() # Prints "This is J.meth1 implemented by D."
Or use different syntax to be more explicit.
I.meth1(d,1,2) # Same as I(d).meth1(1,2) J.meth1(d) # Same as J(d).meth1()
Please let me know if I'm just insane for sleep deprivation!
jw
- Previous message: [Python-Dev] Urgent: regex Perl vs Python
- Next message: [Python-Dev] Re: *very* revised proposal for interfaces
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]