By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,302 Members | 1,788 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,302 IT Pros & Developers. It's quick & easy.

Python "implements <interface>" equivalent?

P: n/a
Hi,

I recently started using Python and am extremely happy with how
productive it's made me, even as a new user. I'm hoping to continue
using the language for my research, and have come across a bit of a
stumbling block.

I'm a seasoned Java programmer and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.

Is there something similar in Python?

What I'd like to do is create a feature detection system for my work
-- specifically, a general class / interface called "Feature" and then
subclasses that implement functions like isFeaturePresent() in all of
their different and unique ways. I'd love to hear how I can do this in
Python.

Thanks,
Wojciech

Oct 4 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Wojciech Gryc napisa³(a):
I'm a seasoned Java programmer and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.

Is there something similar in Python?
The closest thing I saw is zope.interface.
What I'd like to do is create a feature detection system for my work
-- specifically, a general class / interface called "Feature" and then
subclasses that implement functions like isFeaturePresent() in all of
their different and unique ways. I'd love to hear how I can do this in
Python.
I am sure you wouldn't need interfaces to do such things in Python.
"Duck typing" is how we call this feature. :)

--
Jarek Zgoda
Skype: jzgoda | GTalk: zg***@jabber.aster.pl | voice: +48228430101

"We read Knuth so you don't have to." (Tim Peters)
Oct 4 '07 #2

P: n/a
On Oct 4, 11:11 am, Wojciech Gryc <wojci...@gmail.comwrote:
Hi,

I recently started using Python and am extremely happy with how
productive it's made me, even as a new user. I'm hoping to continue
using the language for my research, and have come across a bit of a
stumbling block.

I'm a seasoned Java programmer and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.

Is there something similar in Python?

Yes: you do it pretty much the same way you'd do it in Java, except
for two differences:
* leave out the "implements Interface" part
* don't actually create an Interface class

And then, voila!, you can write functions that can accept any class
that implements your interface.

What I'd like to do is create a feature detection system for my work
-- specifically, a general class / interface called "Feature" and then
subclasses that implement functions like isFeaturePresent() in all of
their different and unique ways. I'd love to hear how I can do this in
Python.
Just define isFeaturePresent() in any class you want. That's all you
have to do; any class that defines this method can be passed to any
function that invokes it, without having to "implement" or "subclass"
anything.

This is known as "duck typing" in Python lingo.
Carl Banks

Oct 4 '07 #3

P: n/a
Thank you Carl and thank you Jarek. This makes me feel much better --
on to coding, I shall go. :)

Thanks again,
Wojciech

On Oct 4, 11:27 am, Carl Banks <pavlovevide...@gmail.comwrote:
On Oct 4, 11:11 am, Wojciech Gryc <wojci...@gmail.comwrote:
Hi,
I recently started using Python and am extremely happy with how
productive it's made me, even as a new user. I'm hoping to continue
using the language for my research, and have come across a bit of a
stumbling block.
I'm a seasoned Java programmer and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.
Is there something similar in Python?

Yes: you do it pretty much the same way you'd do it in Java, except
for two differences:
* leave out the "implements Interface" part
* don't actually create an Interface class

And then, voila!, you can write functions that can accept any class
that implements your interface.
What I'd like to do is create a feature detection system for my work
-- specifically, a general class / interface called "Feature" and then
subclasses that implement functions like isFeaturePresent() in all of
their different and unique ways. I'd love to hear how I can do this in
Python.

Just define isFeaturePresent() in any class you want. That's all you
have to do; any class that defines this method can be passed to any
function that invokes it, without having to "implement" or "subclass"
anything.

This is known as "duck typing" in Python lingo.

Carl Banks

Oct 4 '07 #4

P: n/a
Wojciech Gryc a écrit :
Hi,

I recently started using Python and am extremely happy with how
productive it's made me, even as a new user. I'm hoping to continue
using the language for my research, and have come across a bit of a
stumbling block.

I'm a seasoned Java programmer
So you may want to read this:

http://dirtsimple.org/2004/12/python-is-not-java.html

http://dirtsimple.org/2004/12/java-i...on-either.html
and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.

Is there something similar in Python?
Yes, and it's even simpler : just pass your object. If it effectively
implements the desired interface, everything will work fine !-)

IOW : Python is dynamically typed, there's no parameters type
declaration and no parameters type checking at compile time - so you
just don't need to tell the compiler that your class implements a given
interface. Anyway, this would be a waste of time since you can
add/delete/replace attributes and methods at runtime either on a
per-class or per-instance basis.
What I'd like to do is create a feature detection system for my work
-- specifically, a general class / interface called "Feature" and then
subclasses that implement functions like isFeaturePresent() in all of
their different and unique ways. I'd love to hear how I can do this in
Python.
I'm not sure about what you exactly want to do, but FWIW, checking if an
object has a given attribute is quite simple:

if has_attr(obj, 'attribute_name'):
print "Hurray"
else:
print "D'oh"

Note that in Python, methods are attributes too - only they are callable.
Thanks,
Wojciech
Oct 4 '07 #5

P: n/a
On 2007-10-04, Bruno Desthuilliers <br********************@wtf.websiteburo.oops.comwr ote:
Yes, and it's even simpler : just pass your object. If it effectively
implements the desired interface, everything will work fine !-)
[...]
>What I'd like to do is create a feature detection system for
my work -- specifically, a general class / interface called
"Feature" and then subclasses that implement functions like
isFeaturePresent() in all of their different and unique ways.
I'd love to hear how I can do this in Python.

I'm not sure about what you exactly want to do, but FWIW, checking if an
object has a given attribute is quite simple:

if has_attr(obj, 'attribute_name'):
print "Hurray"
else:
print "D'oh"

Note that in Python, methods are attributes too - only they
are callable.
On a slight tangent....

The "Pythonic" way to handle things like that is often just
to call the method you want to call. If the object doesn't
have that method, then you catch the exception and do whatever
it is you do in the case where the object doesn't have the
feature in question.

The tricky bit is only catching the AttributeError exception
generated by the attempt to access the non-existant method, and
not catching AttributeError exceptions generated by bugs in the
method when it does exist.

Once you've added code to make sure you only catch exceptions
you care about, it's simpler to just call has_attr

the obvious method

try:
myobj.feature1()
except AttributeError:
print "object doesn't implement feature1"

isn't correct, since an unhandled AttributeError generated by
the feature1 method will print "object doesn't implement
feature1". Attempting to isolate the attributeError we care
about looks like this:

try:
m = myobj.feature1
except AttributeError:
print "object doesn't implement feature1"
else:
m()

That's just too messy compared with the has_attr method that
goes like this:

if has_attr(myobj,'feature1'):
myobj.feature1()
else:
print "object doesn't implement feature1"

However, I don't like that alot because you've got to supply
the method name twice: once as a string and once as the method
name.

What's the cleanest way to call a method that might not be
there?

--
Grant Edwards grante Yow! My haircut is totally
at traditional!
visi.com
Oct 4 '07 #6

P: n/a
Grant Edwards a écrit :
On 2007-10-04, Bruno Desthuilliers <br********************@wtf.websiteburo.oops.comwr ote:

>>Yes, and it's even simpler : just pass your object. If it effectively
implements the desired interface, everything will work fine !-)

[...]

>>>What I'd like to do is create a feature detection system for
my work -- specifically, a general class / interface called
"Feature" and then subclasses that implement functions like
isFeaturePresent() in all of their different and unique ways.
I'd love to hear how I can do this in Python.

I'm not sure about what you exactly want to do, but FWIW, checking if an
object has a given attribute is quite simple:

if has_attr(obj, 'attribute_name'):
print "Hurray"
else:
print "D'oh"

Note that in Python, methods are attributes too - only they
are callable.


On a slight tangent....

The "Pythonic" way to handle things like that is often just
to call the method you want to call. If the object doesn't
have that method, then you catch the exception and do whatever
it is you do in the case where the object doesn't have the
feature in question.
Depends... If you expect the object to have this attribute most of the
time, then the try/except solution is fine, but else it might be better
to look-before-you-leap - try/except blocks are costly when there's
effectively an exception.

As a side note, you may not necessarily want to actually call the
method, only know if it's there. As a side-side note, if you want to
call it but choose the look-before-you-leap approach, using getattr()
and storing a local reference to the method might be better, since it
avoids a second lookup.
>
The tricky bit is only catching the AttributeError exception
generated by the attempt to access the non-existant method, and
not catching AttributeError exceptions generated by bugs in the
method when it does exist.

Once you've added code to make sure you only catch exceptions
you care about, it's simpler to just call has_attr

the obvious method

try:
myobj.feature1()
except AttributeError:
print "object doesn't implement feature1"

isn't correct, since an unhandled AttributeError generated by
the feature1 method will print "object doesn't implement
feature1".
Indeed. In this case, it would be better to *not* catch the exception.
At least, the traceback will make clear where the AttributeError comes from.
Attempting to isolate the attributeError we care
about looks like this:

try:
m = myobj.feature1
except AttributeError:
print "object doesn't implement feature1"
else:
m()
Which might raise a TypeError if myobj.feature1 is not callable !-)
That's just too messy compared with the has_attr method that
goes like this:

if has_attr(myobj,'feature1'):
myobj.feature1()
else:
print "object doesn't implement feature1"

However, I don't like that alot because you've got to supply
the method name twice: once as a string and once as the method
name.

What's the cleanest way to call a method that might not be
there?
m = getattr(myobj, 'feature1', None)
if callable(m):
m()
else:
print "%s doesn't implement feature1()" % myobj
Oct 4 '07 #7

P: n/a

"Wojciech Gryc" <wo******@gmail.comwrote in message
news:11**********************@57g2000hsv.googlegro ups.com...
| Hi,
|
| I recently started using Python and am extremely happy with how
| productive it's made me, even as a new user. I'm hoping to continue
| using the language for my research, and have come across a bit of a
| stumbling block.
|
| I'm a seasoned Java programmer and quite a big fan of interfaces...
| i.e. The idea that if I make a number of distinct classes that
| implement interface X, I can pass them all as parameters to functions
| or whatnot that require an X object.
|
| Is there something similar in Python?

As others have noted, without typechecks, Python code is generic. For
example, 'a+b' means "Try a.__add__(b). If that does not work, try
b.__radd__(a). If that does not, raise an error."

| What I'd like to do is create a feature detection system for my work
| -- specifically, a general class / interface called "Feature" and then
| subclasses that implement functions like isFeaturePresent() in all of
| their different and unique ways. I'd love to hear how I can do this in
| Python.

If you have several methods (with multiple implementations), an abstract
base class can be helpful:

class Feature(object):
def isFeaturePresent(self):
raise NotImplementedError
def otherMethod(self):
raise NotImplementedError
# etc

Inherit from Feature (and possibly other classes -- Python has multiple
inheritance) to make your subclasses. Then put 'if not isinstance(arg,
Feature): raise TypeError(func requires Features)' at the top of functions
that work on Features. If you call Feature methods more than once in a
function, this save multiple checks or try-except blocks.

The cost, of course, is the inheritance requirement.

Terry Jan Reedy

Oct 4 '07 #8

P: n/a
In message <11**********************@57g2000hsv.googlegroups. com>, Wojciech
Gryc wrote:
I'm a seasoned Java programmer and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.
Why?

Interfaces are just a euphemism for multiple inheritance, except it's sort
of a crippled compromise to keep the single-inheritance fanatics from
getting too unhappy.
Oct 5 '07 #9

P: n/a
Grant Edwards <gr****@visi.comwrote:
try:
myobj.feature1()
except AttributeError:
print "object doesn't implement feature1"

isn't correct, since an unhandled AttributeError generated by
the feature1 method will print "object doesn't implement
feature1".
I'd be tempted to argue that it *was* correct, since the object
doesn't implement a feature1 which can be used. (This is the cue
for someone to talk about making sure that myobj's class has
been thoroughly unit tested.)

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
"Frankly I have no feelings towards penguins one way or the other"
-- Arthur C. Clarke
her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump
Oct 5 '07 #10

P: n/a
I'm a seasoned Java programmer and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.

Is there something similar in Python?
Python will probably be getting Abstract Base Classes at some point.

http://www.python.org/dev/peps/pep-3119/

For ABC in current versions of Python, see the "Can you implement
abstract classes in Python in 0 lines of code? Or 4?" question on this
page: http://norvig.com/python-iaq.html

David.
Oct 5 '07 #11

P: n/a
Lawrence D'Oliveiro a écrit :
In message <11**********************@57g2000hsv.googlegroups. com>, Wojciech
Gryc wrote:

>>I'm a seasoned Java programmer and quite a big fan of interfaces...
i.e. The idea that if I make a number of distinct classes that
implement interface X, I can pass them all as parameters to functions
or whatnot that require an X object.


Why?

Interfaces are just a euphemism for multiple inheritance,
Java's 'interface' mechanism is mostly a (somewhat weak & dumb IMHO)
mean to decouple (sub)typing from implementation. Given a declarative
static type system and the restriction to single implementation
inheritance, of course. IIRC, vb6 had *no* implementation inheritance at
all - you had to do 'implement' it by yourself, using (manual of course)
delegation...

Now multiple inheritence is clearly not the answer to the OP's question
in a dynamically typed language, where subtyping is not bound to
inheritance.
Oct 5 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.