Python "implements <interface>" equivalent?

Grant Edwards grante at visi.com
Thu Oct 4 13:44:44 EDT 2007


On 2007-10-04, Bruno Desthuilliers <bruno.42.desthuilliers at wtf.websiteburo.oops.com> wrote:

> 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            



More information about the Python-list mailing list