other ways to check for <type 'function'>?

Discussion in 'Python' started by elderic, Nov 2, 2006.

  1. elderic

    elderic Guest

    Hi there,

    are there other ways than the ones below to check for <type 'function'>
    in a python script?
    (partly inspired by wrapping Tkinter :p)

    def f():
    print "This is f(). Godspeed!"

    1.: --> sort of clumsy and discouraged by the docs as far as I read
    import types
    type(f) is types.FunctionType

    2.: --> I don't like this one at all
    def null(): pass
    type(f) is type(null)

    Basically I'm searching for something like:
    "type(f) is func" like in: "type(x) is int"

    Any ideas? =)
    elderic, Nov 2, 2006
    #1
    1. Advertising

  2. elderic wrote:

    > are there other ways than the ones below to check for <type 'function'>
    > in a python script?


    callable(f)

    </F>
    Fredrik Lundh, Nov 2, 2006
    #2
    1. Advertising

  3. elderic

    elderic Guest

    Thx =)

    Fredrik Lundh schrieb:

    > elderic wrote:
    >
    > > are there other ways than the ones below to check for <type 'function'>
    > > in a python script?

    >
    > callable(f)
    >
    > </F>
    elderic, Nov 2, 2006
    #3
  4. elderic enlightened us with:
    > are there other ways than the ones below to check for <type
    > 'function'> in a python script?


    First of all, why would you want to? If you want to call the object
    as a function, just do so. Handle the exception that is raised when
    it's raised.

    Sybren
    --
    Sybren Stüvel
    Stüvel IT - http://www.stuvel.eu/
    Sybren Stuvel, Nov 2, 2006
    #4
  5. elderic

    Christophe Guest

    Sybren Stuvel a écrit :
    > elderic enlightened us with:
    >> are there other ways than the ones below to check for <type
    >> 'function'> in a python script?

    >
    > First of all, why would you want to? If you want to call the object
    > as a function, just do so. Handle the exception that is raised when
    > it's raised.


    I don't think it's a good idea because when you place a try catch block
    around a function call, you'll catch any exception thrown by the
    function itself and not only the "cannot be called" exception.
    Christophe, Nov 2, 2006
    #5
  6. Sybren Stuvel schrieb:
    > elderic enlightened us with:
    >> are there other ways than the ones below to check for <type
    >> 'function'> in a python script?

    >
    > First of all, why would you want to? If you want to call the object
    > as a function, just do so. Handle the exception that is raised when
    > it's raised.


    That's an advice I've heard a few times to often.

    I'm totally buying duck-typing. Yet the advice of simply calling a
    function to determine that it is one isn't sound in a lot of cases where
    you want to use it as callback later on.

    E.g. the turbogears DataGrid can get either a string or a callable
    passed as column-data-provider. But which of these two options is used
    must be known at construction time, not at later calling time.

    Diez
    Diez B. Roggisch, Nov 2, 2006
    #6
  7. elderic

    Guest

    Christophe wrote:
    > Sybren Stuvel a écrit :
    > > elderic enlightened us with:
    > >> are there other ways than the ones below to check for <type
    > >> 'function'> in a python script?

    > >
    > > First of all, why would you want to? If you want to call the object
    > > as a function, just do so. Handle the exception that is raised when
    > > it's raised.

    >
    > I don't think it's a good idea because when you place a try catch block
    > around a function call, you'll catch any exception thrown by the
    > function itself and not only the "cannot be called" exception.


    A little experimentation shows that when something is not callable
    always a TypeError which evaluates to "'<type>' object is not
    callable", so you can refine the try/catch with this information

    py> x = 1
    py> x()
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    py> x = ''
    py> x()
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: 'str' object is not callable
    py> class x:
    .... pass
    ....
    py> x()
    <__main__.x instance at 0x1002eef38>
    py> def x():
    py. pass
    py.
    py> x()
    , Nov 2, 2006
    #7
  8. Christophe enlightened us with:
    > I don't think it's a good idea because when you place a try catch
    > block around a function call, you'll catch any exception thrown by
    > the function itself and not only the "cannot be called" exception.


    That depends on the exception you're catching, doesn't it?

    Sybren
    --
    Sybren Stüvel
    Stüvel IT - http://www.stuvel.eu/
    Sybren Stuvel, Nov 2, 2006
    #8
  9. wrote:

    > A little experimentation shows that when something is not callable
    > always a TypeError which evaluates to "'<type>' object is not
    > callable"


    that's not defined by the language specification, though, so your code
    won't be portable, and may break in future releases.

    and even if you can live with that, you still cannot distinguish between
    non-callable objects and bugs *inside* the callables, unless you add
    traceback analysis to the exception handler.

    </F>
    Fredrik Lundh, Nov 2, 2006
    #9
  10. elderic

    ArdPy Guest

    elderic wrote:
    > Hi there,
    >
    > are there other ways than the ones below to check for <type 'function'>
    > in a python script?
    > (partly inspired by wrapping Tkinter :p)
    >
    > def f():
    > print "This is f(). Godspeed!"
    >
    > 1.: --> sort of clumsy and discouraged by the docs as far as I read
    > import types
    > type(f) is types.FunctionType
    >
    > 2.: --> I don't like this one at all
    > def null(): pass
    > type(f) is type(null)
    >
    > Basically I'm searching for something like:
    > "type(f) is func" like in: "type(x) is int"
    >
    > Any ideas? =)


    you could use assert. Like the one below

    assert inspect.isfunction(function_name)
    ArdPy, Nov 2, 2006
    #10
  11. elderic

    Christophe Guest

    Sybren Stuvel a écrit :
    > Christophe enlightened us with:
    >> I don't think it's a good idea because when you place a try catch
    >> block around a function call, you'll catch any exception thrown by
    >> the function itself and not only the "cannot be called" exception.

    >
    > That depends on the exception you're catching, doesn't it?


    And what if the function has an error and calls a non callable object ?
    Christophe, Nov 2, 2006
    #11
  12. elderic

    John Roth Guest

    Fredrik Lundh wrote:
    > elderic wrote:
    >
    > > are there other ways than the ones below to check for <type 'function'>
    > > in a python script?

    >
    > callable(f)
    >
    > </F>


    PEP 3100 specifies that the callable builtin is
    to be removed in Python 3.0, together with what
    I presume is the underlying C support for the
    function.

    Unfortunately, there are cases where it's not
    advisable to call something to verify that it's
    callable - calling it will cause irreversable
    changes to the program state, while a
    verification function should make no changes
    to state. The advice is fundamentally bad
    design.

    On the other claw, I can understand Guido's
    point in wanting to get rid of it - it's got to be
    an ugly piece of code with the Inappropriate
    Intimacy code smell stinking up the place.

    So what to do? Frankly, I'd back up a few
    yards and consider the system design.
    Where is the callable coming from? If it's
    inside the team's scope of control, don't
    bother checking it - the team should have
    tests in place that verify that each site
    passing a callable is passing the correct
    object. If it's coming from outside, define
    what's allowable and check that case by
    case, preferably with consultation with
    your code's clients.

    John Roth
    John Roth, Nov 2, 2006
    #12
  13. John Roth wrote:

    > PEP 3100 specifies that the callable builtin is
    > to be removed in Python 3.0, together with what
    > I presume is the underlying C support for the
    > function.


    PEP 3100 is not even close to being finalized, and does not apply to
    Python 2.X.

    </F>
    Fredrik Lundh, Nov 2, 2006
    #13
  14. elderic

    Guest

    elderic:
    > 1.: --> sort of clumsy and discouraged by the docs as far as I read
    > import types
    > type(f) is types.FunctionType


    What's the problem with this?

    from types import FunctionType
    if isinstance(f, FunctionType):
    ...

    Bye,
    bearophile
    , Nov 2, 2006
    #14
  15. elderic

    elderic Guest

    > What's the problem with this?
    >
    > from types import FunctionType
    > if isinstance(f, FunctionType):
    > ...
    >
    > Bye,
    > bearophile


    Well... it's discouraged by the docs =)

    At least the use of module types.
    I was just wondering if there were some alternatives.
    Never thought I would start off a thread this long =)

    That was basically my reason for asking about something similar like
    the functions list(), dict(), int(), etc... when called without (),
    they return <type 'sometype'>.
    I just wanted to know if there was a keyword for functions, too.

    Then u could've done: type(f) is function
    quite similar to: type(x) is int

    Didn't intent to be a Documentation-Nazi *G*

    -elderic

    Excuse my large paste from the Python 2.5 Documentation:
    ---------------------------------------------------------------------------------------
    5.15 types -- Names for built-in types

    <snip!>

    Typical use is for functions that do different things depending on
    their argument types, like the following:

    from types import *
    def delete(mylist, item):
    if type(item) is IntType:
    del mylist[item]
    else:
    mylist.remove(item)

    Starting in Python 2.2, built-in factory functions such as int() and
    str() are also names for the corresponding types. This is now the
    preferred way to access the type instead of using the types module.
    Accordingly, the example above should be written as follows:

    def delete(mylist, item):
    if isinstance(item, int):
    del mylist[item]
    else:
    mylist.remove(item)
    ---------------------------------------------------------------------------------------
    elderic, Nov 2, 2006
    #15
  16. elderic

    Christophe Guest

    Christophe a écrit :
    > Sybren Stuvel a écrit :
    >> Christophe enlightened us with:
    >>> I don't think it's a good idea because when you place a try catch
    >>> block around a function call, you'll catch any exception thrown by
    >>> the function itself and not only the "cannot be called" exception.

    >>
    >> That depends on the exception you're catching, doesn't it?

    >
    > And what if the function has an error and calls a non callable object ?

    Or even worse. Since we have :

    >>> None()

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: 'NoneType' object is not callable
    >>> 1+""

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    >>> ""+1

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: cannot concatenate 'str' and 'int' objects

    All of them are TypeError exceptions. It is extremly dangerous to put a
    try except TypeError clause around a function call to catch the case
    where the function object isn't a callable :/
    Christophe, Nov 2, 2006
    #16
  17. elderic wrote:

    > I just wanted to know if there was a keyword for functions, too.
    >
    > Then u could've done: type(f) is function
    > quite similar to: type(x) is int


    but why do you think you need that, when you have callable() ? unless
    you're doing specialized stuff, there's really no reason to distinguish
    between function objects and other callables.

    </F>
    Fredrik Lundh, Nov 2, 2006
    #17
  18. elderic

    elderic Guest

    > > I just wanted to know if there was a keyword for functions, too.
    > >
    > > Then u could've done: type(f) is function
    > > quite similar to: type(x) is int

    >
    > but why do you think you need that, when you have callable() ? unless
    > you're doing specialized stuff, there's really no reason to distinguish
    > between function objects and other callables.
    >
    > </F>


    I never said that I need anything - I merely asked for alternatives. =)
    I'm pretty happy with the types-module or the callable() test.

    Basically it's just for wrapping the creation of Tk-Buttons, etc.
    They need a callback and in my process to learn I wanted to know about
    the
    possible options to test for that.

    peace of mind. =)
    elderic
    elderic, Nov 2, 2006
    #18
  19. elderic wrote:

    > I never said that I need anything - I merely asked for alternatives. =)
    > I'm pretty happy with the types-module or the callable() test.
    >
    > Basically it's just for wrapping the creation of Tk-Buttons, etc.
    > They need a callback and in my process to learn I wanted to know about
    > the possible options to test for that.


    the more reason not to even think about using anything but "callable".
    many things in Python are callable; an explicit function test would
    disallow several interesting alternatives:

    >>> def foo():

    .... pass
    ....
    >>> class fum:

    .... def bar(self):
    .... pass
    .... def __call__(self):
    .... pass
    ....
    >>> type(foo) is type(fum)

    False
    >>> f = fum()
    >>> type(foo) is type(f)

    False
    >>> type(foo) is type(f.bar)

    False

    etc.

    (and I really shouldn't ask why you cannot just use Tkinter, and spend
    your time and energy on something more worthwhile ? if not else, there
    are plenty of Tk extensions that could need nice wrappers...)

    </F>
    Fredrik Lundh, Nov 2, 2006
    #19
  20. elderic

    Guest

    Python should have a TypeError subclass: "NotCallableError", to enforce
    BAFP.
    , Nov 3, 2006
    #20
    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. Davisro
    Replies:
    1
    Views:
    683
    Michael D. Ober
    Jun 14, 2004
  2. Merennulli
    Replies:
    2
    Views:
    919
    Merennulli
    Mar 14, 2006
  3. Replies:
    20
    Views:
    2,181
  4. NotGuru
    Replies:
    3
    Views:
    423
    NotGuru
    Mar 24, 2008
  5. Simon Schuster
    Replies:
    6
    Views:
    87
    Rick DeNatale
    Oct 2, 2007
Loading...

Share This Page