I see that Python is missing "interfaces". The concept of an interface
is a key to good programming design in Java, but I've read that they
aren't really necessary in Python. I am wondering what technique I can
use in Python to get the same benefits to a program design that I would
get with interfaces in Java.
For example, if I want to have a program with a Car object, and a Bus
object. I want both of these objects to present a common group of
methods that can be used by Mechanic objects, but slightly different
methods that can be used by Driver objects.
In Java I would accomplish this by defining an IFixable interface that
would be implemented by both the Car and Bus objects. Mechanic objects
would work with any object implementing this interface.
How would I approach this problem in Python? I think I would use an
abstract class instead of an interface for IFixable, since Python
supports multiple inheritance, but I'm not sure this is correct.
Thanks for any suggestions.
Scott Huey
No it isn't. It just hasn't got them.
> The concept of an interface is a key to good programming design in
> Java, but I've read that they aren't really necessary in Python.
> In Java I would accomplish this by defining an IFixable interface
> that would be implemented by both the Car and Bus objects. Mechanic
> objects would work with any object implementing this interface.
In Python, you would simply call the functions you need. No need to
make things that rigidly defined.
Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Except when you need to handle exceptions when those methods don't
exist. I think interfaces can definitely be useful.
--
Jonathan Daugherty
http://www.parsed.org
> # In Python, you would simply call the functions you need. No need to
> # make things that rigidly defined.
>
> Except when you need to handle exceptions when those methods don't
> exist. I think interfaces can definitely be useful.
so with interfaces, missing methods will suddenly appear out of thin
air ?
</F>
With interfaces, the idea is that they're enforced; so, they'll appear
because someone implements them.
> # so with interfaces, missing methods will suddenly appear out of thin
> # air ?
>
> With interfaces, the idea is that they're enforced; so, they'll appear
> because someone implements them.
enforced by whom, at what point ?
</F>
If the mechanic class had a "fixIt()" method defined, could I pass it
any object I wanted, and then just call the method that I expect to
find there, or do I need to strictly define the type, or class, of an
object that is passed to a method.
Scott Huey
In the case of Java, I think the JVM enforces interface implementation
(probably at the parser level).
Zope 3 has an interface system which is good. I recommend you look at
that.
> If the mechanic class had a "fixIt()" method defined, could I pass it
> any object I wanted
absolutely.
> and then just call the method that I expect to find there
yes.
> or do I need to strictly define the type, or class, of an object that is
> passed to a method.
no. this is Python. no need to negotiate with the compiler; just do what
you want, and the interpreter will tell you when that doesn't work.
also see:
http://en.wikipedia.org/wiki/Duck_typing
</F>
Zope 3's interface system is quite good, but it's also quite different
from what he's probably expecting. On the up side, it's probably much
better than what he's expecting too. :)
--
Benji York
Have a look at Zope 3.
(http://www.zope.org/DevHome/Wikis/DevSite/Projects/ComponentArchitecture/FrontPage).
It has an interface implementation. You can use this implementation with
the apllication server Zope 3 or alone.
Regards,
Egon
- --
Egon Frerich, Freudenbergstr. 16, 28213 Bremen
E-Mail: e.fr...@nord-com.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (MingW32)
Comment: GnuPT 2.7.2
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFERAsZuTzybIiyjvURAn4wAJ4qCaqAZu4BmnZzrltVAneyWwmh+wCeI8DV
DwNlvYJed/22Ls8Jct4fKV4=
=8eTo
-----END PGP SIGNATURE-----
To use interfaces in python, just what you would do in Java, except
don't use interfaces.
To expand on that slightly Zen answer, think about why you use
interfaces in Java. The interface declaration tells the compiler that
your object implements a specific set of functions, or that your
function expects an object that implements these functions. Then, at
run time, the actual type of the object is used to decide what function
to call.
However, python doesn't to any type checking at compile time, so it
just uses the dynamic type of the object to decide what function to
call.
> How would I approach this problem in Python? I think I would use an
> abstract class instead of an interface for IFixable, since Python
> supports multiple inheritance, but I'm not sure this is correct.
Concretely:
class Car:
def fix(self):
print "Your car is ready, sir"
class Bus:
def fix(self):
print "Your bus is ready, sir"
class Mechanic:
def repair(self, customer, vehicle):
vehicle.fix()
customer.bill()
class Customer:
def bill(self):
print "Ouch, that was expensive"
me = Customer()
my_bus = Bus()
my_car = Car()
m = Mechanic()
m.repair(me, my_bus)
m.repair(me, my_car)
Which gives the output:
Your bus is ready, sir
Ouch, that was expensive
Your car is ready, sir
Ouch, that was expensive
If you try and repair something that can't be fixed:
m.repair(me, me)
you get:
Traceback (most recent call last):
File "test.py", line 30, in ?
m.repair(me, me)
File "test.py", line 14, in repair
vehicle.fix()
AttributeError: Customer instance has no attribute 'fix'
Obviously, you don't want this to happen when people use your program.
Java would check this at compile time, but as python doesn't, you can
write a unit test to check that the object's you want to implement the
relevant functions really do.
def is_fixable(obj):
try:
obj.fix
except AttributeError:
return False
return True
assert is_fixable(Car())
assert is_fixable(Bus())
assert not is_fixable(Customer())
assert not is_fixable(Mechanic())
You will find that most Python programmers bristle at words like
"missing", "enforcement" and "strictly defined the type". Python
programmers just don't work that way. The fact that programmers in
other languages must, is their loss.
-Larry Bates
I think I see what you mean, but that's an odd way to put it.
Typically, you aren't going to handle the exceptions produced by type
errors. Of course, you want some way to test that your code doesn't
have type errors. Static type checking is one way of doing the
requisite testing, unit tests are another, but it's the tests that are
useful, not the interfaces per se. Adding interfaces to python, which
doesn't support static type checking, would be useless IMO.
Python is a very dynamic language. Java is a very static language.
What that means is that in Java (like C++), you do a lot of error
checking at compile time. That's what interfaces are all about. In
Python, you do almost no error checking (beyond basic language syntax)
at compile time, and do everything at run time. For the most part,
this means wrapping things in try blocks and catching exceptions.
>For example, if I want to have a program with a Car object, and a Bus
>object. I want both of these objects to present a common group of
>methods that can be used by Mechanic objects, but slightly different
>methods that can be used by Driver objects.
>
>In Java I would accomplish this by defining an IFixable interface that
>would be implemented by both the Car and Bus objects. Mechanic objects
>would work with any object implementing this interface.
>
>How would I approach this problem in Python? I think I would use an
>abstract class instead of an interface for IFixable, since Python
>supports multiple inheritance, but I'm not sure this is correct.
Well, let's say your IFixable interface in Java would have included
changeTire(), rechargeBattery(), and adjustBrakes() methods. In
Python, I'd just go ahead and implement those methods for both Car and
Bus classes. All Java's interface mechanism does for you is provide
some compile-time checking that those methods are implemented. In
Python, you would just call those methods when appropriate, and catch
any NameError exception that would happen if it turns out there is no
such method.
Consider that in Python, an object can have methods added to it after
it is created. It's entirely possible that the Car class has no
changeTire() method, but one would be added to each Car instance
sometime before the first place it might be called. Consider
something like:
if self.owner.hasRoadsideAssistance():
self.changeTire = callForHelp
elif self.owner.canFixThings:
self.changeTire = getHandsDirty
Now, calling myCar.changeTire() could end up calling callForHelp(), or
calling getHandsDirty(), or throwing NameError is no way exists to get
the tire fixed. Maybe that's what makes sense in your application.
But if you're writing tests you will check method signatures anyway, so
why bother? Besides how java-like interfaces will help you if one of
interface methods is supposed to accept one parameter that can be list
or dict and not accept None?
Most of us came to Python from some other language background ;-)
> I see that Python is missing "interfaces".
As someone else noted, Python objectively does not have 'interfaces' (or
'protocols') as an object type in the language. (But 'missing' is somewhat
subjective.) On the other hand, the concepts are very much part of the
language. See the article on duck typing, which could be called duck
interfacing, that someone gave a link for.
For example, an iterator (newer definition) is an object with an __iter__()
method returning self and a next() method that returns objects until it
raises StopIteration. An iterable is an object with an __iter__() method
that return an iterator. (Hence, iterators are conveniently iterables
also.) Instead of declaring that a class implements IterableInterface, you
just implement it (and the corresponding iterator class if needed) and use
it anywhere an iterable is expected, which is lots places in the builtins
and standard library.
> How would I approach this problem in Python? I think I would use an
> abstract class instead of an interface for IFixable, since Python
> supports multiple inheritance, but I'm not sure this is correct.
I believe this
>>> NotImplementedError
<class exceptions.NotImplementedError at 0x00974810>
was added so that people could go the route of abstract base classes with
stub functions.
Terry Jan Reedy
> # enforced by whom, at what point ?
>
> In the case of Java, I think the JVM enforces interface implementation
> (probably at the parser level).
"parser"...?! If you have an 'Object o', say one just received as an
argument, and cast it to IBlahble, a la
IBlahble blah = (IBlahble) o;
...what can the parser ever say about it? It's clearly up to the
runtime system to "enforce" whatever -- raising the appropriate
exception if the "actual" (leafmost) class of o does not in fact
implement IBlahble (Java doesn't _really_ do compile-time static typing:
it just forces you to violate the "Don't Repeat Yourself" cardinal rule
by redundantly repeating types, as above, but then in general it checks
things at runtime anyway!).
Alex
Maybe you didn't read the "I think" in my OP. Anyway, you clearly
know more about (or have more recent experience with) Java than I do.
> # "parser"...?! If you have an 'Object o', say one just received as an
> # argument, and cast it to IBlahble, a la
> #
> # IBlahble blah = (IBlahble) o;
> #
> # ...what can the parser ever say about it?
>
> Maybe you didn't read the "I think" in my OP. Anyway, you clearly
> know more about (or have more recent experience with) Java than I do.
My real-world experience with Java is very dated -- nowadays, I'm told,
the NEED to cast is vastly reduced by Java 1.5's "generics" (I haven't
yet written one line of Java 1.5, not even for "play" purposes, much
less "real world" ones;-). Still, all the casting that used to work
still works, so the purported "compile-time type safety" is worth as
much as the social compact to "don't use any of the container classes
that used to work until 1.4.*, but ONLY the very newest ones in 1.5"!-)
So much for "compiler enforcement", hm?-)
Alex
Interesting; thanks.
# So much for "compiler enforcement", hm?-)
Yes, indeed. :)
http://www.artima.com/weblogs/viewpost.jsp?thread=92662
--
Pablo
+1 QOTW
So for good and flexible OOP in C# someone should use interfaces
because it is the only way to achive the flexibility needed but in
python because of duck typing you always get the flexibility without
you doing anything special like trying to come up with a type that
accommodates some common ground of other types, so as someone say here
"To use interfaces in python, just do what you would do in Java, except
don't use interfaces."
So to digress a little, for me the difference is that in C# you are
given safety, documentation (read app. domain definitions) and
track-ability (read refactoring, intelisense) but you have to code for
flexibility while in python you are given flexibility but you have to
code for safety and documentation and as far as for track-ability you
are usually out of luck. Now many people agree that the safety you are
given in C# is usually far from ideal (no app. domain logic safety
given) so usually you have to code for that as well as in python, and
my opinion is that the documentation provided by type definition wile
ok, for best maintainability you have to provide comments anyway about
their app. domain means just like you do in python, so the only think
that is different is that the lack of track-ability in python is
sometime annoying for me now when I'm going back to python after a
little bit of C#, but the annoyance is even bigger when in C# I always
have to think ahead of time how to make sure that my code if flexible
enough to support easy changing.
Gheorghe Milas
Everyone is getting off track here.
Java has interfaces because it doesn't support multiple inheritance.
Python supports MI, so you don't need to use the seperate concept of an
interface. You're right that an abstract class is the equivilent of an
interface. Just create a ABC that raises NotImplementedExceptions for
each of the methods, and use that class as one of the base classes. Of
course, like a lot of stuff in python, this won't throw an exception at
'compile-time', only when you try to invoke a method that has no
implemenation.
The general wisdom is that Abstract Base Classes aren't pythonic
though. If you want to be pythonic, just implement the methods for
your 'interface', and (if necessary) check for their existance with
hasattr before calling (or even just call the method and you'll get an
attribute error anyway). This is referred to as duck-typing. If it
looks like a duck, and quacks like a duck, then for all practical
purposes it supports the 'duck' interface.
The problem with that of course, is that there's much more to being a duck
than being called 'duck'.
public interface JarFile {
void explode();
}
public interface NuclearBomb {
void explode();
}
http://www.beust.com/weblog/archives/000269.html
--
René Pijlman
He probably means that with interfaces one could test compliance with
the interface as a whole instead of testing each member and each
signature as a single piece.
Peter Maas, Aachen
What is the difference between "static" and "very static"? Is Java
more static than Fortran I? ;)
Peter Maas, Aachen
Not that I disagree with you, but interfaces don't really guarantee any
semantics either. You'd probably need to use Eiffel if you really want
to design by contract.
public class EarFile implements JarFile {
void explode()
{
HackerTools.WipeHardDrive();
}
}
All interfaces (as implemented by Java) prove is that your class has a
bunch of methods with the right names and signatures. It doesn't
prove that those methods do the right things. It's like having a
bouncer in front of a nightclub stopping people saying, "You can't
come in here unless you tell me you're over 21 and aren't wearing
scruffy jeans". OK, I'm happy to tell you that, but if you don't
check to make sure it's true, you're going to have a lot of scruffy 18
year olds crashing your party.
I don't think anyone is suggesting that interfaces do (or should)
prove that the implemented methods actually do the right thing.
> Peter Maas <peter...@somewhere.com> wrote:
> > He probably means that with interfaces one could test compliance
> > with the interface as a whole instead of testing each member and
> > each signature as a single piece.
>
> All interfaces (as implemented by Java) prove is that your class has a
> bunch of methods with the right names and signatures. It doesn't
> prove that those methods do the right things. It's like having a
There's a _tiny_ bit more -- accidental clashes of methodnames are more
likely to be avoided. I.e.,
interface ILottery {
void draw();
};
interface IGunslinger {
void draw();
};
interface IPainter {
void draw();
};
A class asserting, e.g., "implements IPainter", doesn't thereby risk
being accidentally misused where an IGunslinger is required (OTOH,
implementing >1 of these IS a bother, but that's sort of inevitable).
Alex
The answer is called "duck typing" or "structural typing". Any two
classes that implement a set of methods with pairwise equal signatures
can be considered as "presenting a group of methods". You do not have
to create a special construct and assign it to classes ( e.g. via an
"implements" directive ) in order to make it work. That's because you
are not enforced to know the type of an object at compile time. Car and
Bus classes may be selected from two completely different libraries
without any common convention but it is still possible ( though not
very likely without any adaption ) that they work together and show
sound behaviour ( you have to prove at least certain behavioural
properties using unit tests ).
"Duck typing" is also the reason why coupling of an interface with an
implementation is not harmfull in Python. You won't find many deep
class hierarchies and extensive frameworks. This has the advantage that
a classification you have done once at the beginning of your project in
the design phase is not considered to be carved in stone.
In Java/C#/C++ you can achieve many of the same effects of using
"generic" or "templates" but if you are not start coding with them from
the very beginning you loose many of their benfits. In Python this is a
non-issue.
Zope comes to mind.
>This has the advantage that a classification you have done once at
>the beginning of your project in the design phase is not considered
>to be carved in stone.
Zope 3 comes to mind.
> Everyone is getting off track here.
Not that much...
> Java has interfaces because it doesn't support multiple inheritance.
Java as interfaces because it relies on type declaration for subtyping
*and* doesn't support MI.
> Python supports MI, so you don't need to use the seperate concept of an
> interface.
s/supports MI/doesn't rely on type declaration for subtyping/
Would we need interfaces in Python if Python did not support MI ? Of
course not, duck typing would still work.
(snip)
> The general wisdom is that Abstract Base Classes aren't pythonic
> though.
*Pure* abstract base classes (ie: abc without any implementation) are
not Pythonic. I often use abc's that provides the 'guts' for common
stuff, but are meant to be specialized for use (this is pretty common in
frameworks).
(snip the rest - mostly agree)
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'on...@xiludom.gro'.split('@')])"
Yeps. Now Zope is a world in itself, and is not really pythonic IMHO.
It seems to me that a lot of python projects reimplement interfaces or
adaption of some kind once they reach a certain size (Zope, PEAK, eggs,
TurboGears, etc), which implies that they really do have some benefits,
particularly in documentation.
Cheers,
Ben
I suppose, but all you've really done is move the problem to a different
namespace. Which IPainter did you have in mind? The one that has to do
with people who apply oils to canvas, or the one that has to do with ropes
that are used to tie up rowboats?
> I'm coming from a Java background, so please don't stone me...
>
> I see that Python is missing "interfaces". The concept of an interface
> is a key to good programming design in Java, but I've read that they
> aren't really necessary in Python. I am wondering what technique I can
> use in Python to get the same benefits to a program design that I would
> get with interfaces in Java.
>
> For example, if I want to have a program with a Car object, and a Bus
> object. I want both of these objects to present a common group of
> methods that can be used by Mechanic objects, but slightly different
> methods that can be used by Driver objects.
>
> In Java I would accomplish this by defining an IFixable interface that
> would be implemented by both the Car and Bus objects. Mechanic objects
> would work with any object implementing this interface.
>
> How would I approach this problem in Python? I think I would use an
> abstract class instead of an interface for IFixable, since Python
> supports multiple inheritance, but I'm not sure this is correct.
>
> Thanks for any suggestions.
>
I see various answers that Python doesn't need interfaces. OTOH, there are
responses that some large Python apps have implemented them (e.g., zope).
Does anyone have an explanation of why these large systems felt they needed
to implement interfaces?
In Java's excellent naming convention for modules, there's no ambiguity:
I specifically requested it.aleax.artists.IPainter, or else specifically
requested com.panix.roy.boating.IPainter -- nothing stops any language
with a structured namespace for modules from using that convention.
Alex
This is true. This is one of the things Java does well.
PEAK is an interesting counterexample, particularly since Philip Eby
tends to be "ahead of the curve": it appears that he's determined that
``generic functions'' (with ``multimethods'') are a superior approach,
and seems to have convinced Guido to the point that GFs are the
alternative being actively explored for Py3k. I will admit that, while
still undecided, I'm halfway-convinced enough not to mourn for PEP 246.
((It's possible to implement protocols, a la PyProtocols and as
advocated in PEP 246, in terms of GFs, or viceversa; in PEAK, it's
GFs-in-terms-of-protocols for strictly historical reasons, but the
advantage along various axes seems to be to the
protocols-in-terms-of-GFs camp; since protocols are a strict superset of
interfaces...))
BTW, this _could_ be seen as yet another case of "reimplementing LISP",
since Lisp/CLOS was always based on GFs/multimethods...;-).
Alex
I never noticed PEAK before. Is it well worth studying?
A programming language doesn't need interfaces, unless it insists on
compile time checking of just about everything.
The idea of interfaces arises from the construction and maintenance of
large and complex software systems. It provides a level of abstraction
that makes it easier to talk about a component and document what it
requires from and offers to it's environment.
Also, interfaces can make this documentation first-class objects, so test
tools, IDE's and software design tools can take advantage of it.
These "interface" ("protocol" would be a better name IMHO) systems are
not exactly the same as Java's interfaces. They are mainly used a a way
to describe components and allow for component adaptation and
substitutability. Think of it as a highly decoupled pluggable component
system, not as a language-level subtyping mechanism. BTW, you'll notice
that these projects (Zope, Twisted, PEAK, ...) are mostly large frameworks.
My 2 cents...
Oh yes.
Alex
Yes. On my current largish project I've noticed that, as I refactor
code and make it more and more concise, my classes have aquired pretty
mature interfaces. I've begun thinking that a little inline tool to
check compliance would be helpful at this point.
However, all that refactoring I did to get my classes to that point
would have been much more tedious if I'd been using interface
definitions in early development; changing the interface definition
every time some new problem came up would have been a pain. So I'm
leery of having them in the languge even if we're not forced to use
them. I'm afraid people will start writing interface definitions
first, when they should be taking advantage of the duck typing to allow
easy design changes when necessary. Only after a lot of effort, a lot
of refactoring, and a large part of the problem space explored, will
the interfaces be mature enough that writing interface definitions
would be useful and not a burden. (And let's face it: there aren't
many projects that get that far. :)
Adaptation I have no comment about, not having needed it (yet).
Carl Banks
I guess interfaces are "providing" specifications, and generics are
"receiving" specifications, so single dispatch methods can be identical
to interfaces only "inverted".
Therefore, as there is no interface equivalent of full multi-methods,
it shows that multimethods are the only primative you need to implement
all of the above
Cheers,
Ben
+1 QOTW
Michele Simionato