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

E

elderic

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? =)
 
S

Sybren Stuvel

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
 
C

Christophe

Sybren Stuvel a écrit :
elderic enlightened us with:

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.
 
D

Diez B. Roggisch

Sybren said:
elderic enlightened us with:

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
 
W

wittempj

Christophe said:
Sybren Stuvel a écrit :

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()
 
S

Sybren Stuvel

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
 
F

Fredrik Lundh

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>
 
A

ArdPy

elderic said:
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)
 
C

Christophe

Sybren Stuvel a écrit :
Christophe enlightened us with:

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 ?
 
J

John Roth

Fredrik said:
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
 
F

Fredrik Lundh

John said:
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>
 
B

bearophileHUGS

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
 
E

elderic

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)
---------------------------------------------------------------------------------------
 
C

Christophe

Christophe a écrit :
Sybren Stuvel a écrit :

And what if the function has an error and calls a non callable object ?
Or even worse. Since we have :
Traceback (most recent call last):
Traceback (most recent call last):
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 :/
 
F

Fredrik Lundh

elderic said:
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>
 
E

elderic

I just wanted to know if there was a keyword for functions, too.
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
 
F

Fredrik Lundh

elderic said:
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:
.... pass
........ def bar(self):
.... pass
.... def __call__(self):
.... pass
....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>
 
E

eduardo.padoan

Python should have a TypeError subclass: "NotCallableError", to enforce
BAFP.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top