Python "implements <interface>" equivalent?

Discussion in 'Python' started by Bruno Desthuilliers, Oct 3, 2007.

  1. Grant Edwards a écrit :
    > On 2007-10-04, Bruno Desthuilliers <> 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.


    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
     
    Bruno Desthuilliers, Oct 3, 2007
    #1
    1. Advertising

  2. Lawrence D'Oliveiro a écrit :
    > In message <>, 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.
     
    Bruno Desthuilliers, Oct 4, 2007
    #2
    1. Advertising

  3. 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
     
    Wojciech Gryc, Oct 4, 2007
    #3
  4. Bruno Desthuilliers

    Jarek Zgoda Guest

    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: | voice: +48228430101

    "We read Knuth so you don't have to." (Tim Peters)
     
    Jarek Zgoda, Oct 4, 2007
    #4
  5. Bruno Desthuilliers

    Carl Banks Guest

    On Oct 4, 11:11 am, Wojciech Gryc <> wrote:
    > 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
     
    Carl Banks, Oct 4, 2007
    #5
  6. 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 <> wrote:
    > On Oct 4, 11:11 am, Wojciech Gryc <> wrote:
    >
    > > 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
     
    Wojciech Gryc, Oct 4, 2007
    #6
  7. 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-is-not-python-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
    >
     
    Bruno Desthuilliers, Oct 4, 2007
    #7
  8. On 2007-10-04, Bruno Desthuilliers <> 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
     
    Grant Edwards, Oct 4, 2007
    #8
  9. Bruno Desthuilliers

    Terry Reedy Guest

    "Wojciech Gryc" <> wrote in message
    news:...
    | 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
     
    Terry Reedy, Oct 4, 2007
    #9
  10. In message <>, 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.
     
    Lawrence D'Oliveiro, Oct 5, 2007
    #10
  11. Grant Edwards <> wrote:
    > 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 -- -- 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
     
    Sion Arrowsmith, Oct 5, 2007
    #11
  12. Bruno Desthuilliers

    David Guest

    > 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.
     
    David, Oct 5, 2007
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert Oschler
    Replies:
    0
    Views:
    566
    Robert Oschler
    Nov 13, 2004
  2. Eric Wichterich
    Replies:
    0
    Views:
    363
    Eric Wichterich
    Oct 22, 2003
  3. Replies:
    5
    Views:
    570
  4. Zuisman Moshe
    Replies:
    24
    Views:
    2,984
    Zuisman Moshe
    Apr 21, 2009
  5. Emanuele D'Arrigo

    Does Class implements Interface?

    Emanuele D'Arrigo, Aug 27, 2009, in forum: Python
    Replies:
    7
    Views:
    366
    Zvezdan Petkovic
    Aug 28, 2009
Loading...

Share This Page