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

how to get name of function from within function?

P: n/a
I want to get the name of the function from within the function. Something
like:

def myFunc():
print __myname__
myFunc() 'myFunc'

Really what I want to do is to easily strip off the prefix of a function
name and call another function. Like this:

def prefix_myFunc(a, b, c):
name = __myname__[7:]
call(name, a, b, c)

That would call myFunc(a, b, c).

How do I accomplish this 'elegantly', err...'pythonicly'..=)

Also, is there a way to turn normal positional args into a tuple without
using *? Like this:

def f(a, b, c):
print get_args_as_tuple() f(1, 2, 3)

(1, 2, 3)

I don't want to use
def f(*args):
print args
because I want to keep the error checking capability that comes with using a
fixed number of positional args.

Thank you for the help.

Jul 19 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Christopher J. Bottaro wrote:
I want to get the name of the function from within the function. Something
like:

def myFunc():
print __myname__
myFunc() 'myFunc'
There's not a really good way to do this. Can you give some more detail
on what exactly you're trying to do here? Depending on a function's
name within that function is probably a bad idea...

You *can* do this using a sys._getframe() hack:

py> def my_func():
.... print sys._getframe().f_code.co_name
....
py> my_func()
my_func

But that depends on a non-public API. Also, what do you want to happen
if someone binds another name to your function? The code above will
print the original name even if it's different from the new name(s):

py> g = my_func
py> del my_func
py> g()
my_func
py> my_func()
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
NameError: name 'my_func' is not defined
Also, is there a way to turn normal positional args into a tuple without
using *? Like this:

def f(a, b, c):
print get_args_as_tuple()
f(1, 2, 3)


(1, 2, 3)


Um...

py> def f(a, b, c):
.... print (a, b, c)
....
py> f(1, 2, 3)
(1, 2, 3)

?

STeVe
Jul 19 '05 #2

P: n/a
Steven Bethard wrote:
Christopher J. Bottaro wrote:
I want to get the name of the function from within the function.
Something like:

def myFunc():
print __myname__
> myFunc()

'myFunc'


There's not a really good way to do this. Can you give some more detail
on what exactly you're trying to do here?


I want to make wrappers around functions but I can't use __getattr__ because
the functions are being published as a SOAP service and the SOAP lib I'm
using requires a callable object as the argument to the publishing
function.

Basically I want to wrap every function in try/except automatically.
Typically, I suppose people would do that with __getattr__. The way my
code is now is that every function (err, method) is enclosed in the exact
same try/except error handling code. Everytime I make a new function, I
copy/paste that try/catch block. Its ugly, it clutters the code, its prone
to error, and if i decide to change the error handling code later, I have
to change tons of functions.

Actually, I just realized that function call arguments are not passed to
__getattr__, so my idea of wrapping function calls that way won't work.

Is there something like PHP's __call() method in Python?
Also, is there a way to turn normal positional args into a tuple without
using *? Like this:

def f(a, b, c):
print get_args_as_tuple()
>f(1, 2, 3)


(1, 2, 3)


Um...

py> def f(a, b, c):
... print (a, b, c)
...
py> f(1, 2, 3)
(1, 2, 3)

?


In your method, if the name and/or number of positional arguments changes,
the body of the function must change. I want to avoid that.

Thanks.

Jul 19 '05 #3

P: n/a
has
Christopher J. Bottaro wrote:
Basically I want to wrap every function in try/except automatically.


Simplest way to do that would be something like:

def wrapFunction(func):
def wrapper(*args, **kargs):
try:
return func(*args, **kargs)
except Exception, e:
raise # your error handling code here
return wrapper

HTH

Jul 19 '05 #4

P: n/a
Christopher J. Bottaro wrote:
Basically I want to wrap every function in try/except automatically. [snip] every function (err, method) is enclosed in the exact
same try/except error handling code. Everytime I make a new function, I
copy/paste that try/catch block.
Yes, has's suggestion is probably the right way to go here. I'm still
uncertain as to your exact setup here. Are the functions you need to
wrap in a list you have? Are they imported from another module? A
short clip of your current code and what you want it to do would help.

For example, if they are the only thing another module contains, you can
use has's wrapFunction function and do something like:

import functionmodule

for name in dir(functionmodule):
if not name.startswith('_'):
func = wrapFunction(getattr(functionmodule, name))
setattr(functionmodule, name, func)
Is there something like PHP's __call() method in Python?


I don't know. What does PHP's __call() do? I don't know PHP, and it
wasn't in the online manual http://www.php.net/docs.php.
Also, is there a way to turn normal positional args into a tuple without
using *? Like this:

def f(a, b, c):
print get_args_as_tuple()
>>f(1, 2, 3)

(1, 2, 3)


Um...

py> def f(a, b, c):
... print (a, b, c)
...
py> f(1, 2, 3)
(1, 2, 3)

?


In your method, if the name and/or number of positional arguments changes,
the body of the function must change. I want to avoid that.


But if the name and/or number of positional arguments changes, you're
already changing the function definition. What's the real use case
here? Are you really just printing them? Or are you doing something else?

STeVe
Jul 19 '05 #5

P: n/a
Steven Bethard wrote:
[...snip...]
Yes, has's suggestion is probably the right way to go here. I'm still
uncertain as to your exact setup here. Are the functions you need to
wrap in a list you have? Are they imported from another module? A
short clip of your current code and what you want it to do would help.
But I want to avoid having to write each wrapper myself. As it is now, when
I want to add a public method to my class named myFunc, I first write
myFunc which is a wrapper to the implementation:

def myFunc(self):
try: self.myFuncIMPL()
except: # error handling code

def myFuncIMPL(self):
# do the real stuff here, no need to worry about error handling stuff
# cuz its done in the wrapper

I guess I'm just lazy, but I don't want to write the wrapper func for each
new func I want to add. I want it done automatically.
I don't know. What does PHP's __call() do? I don't know PHP, and it
wasn't in the online manual http://www.php.net/docs.php.


http://www.php.net/manual/en/languag...verloading.php

I haven't tried it yet, but this is what I would do with __call():

function __call($name, $args) {
$name .= 'IMPL';
try { $this->$name($args); }
except { # error handling; }
}

function funcA() {
# do something
}

function funcBIMPL($a, $b) {
# do something
}

So I imagine it would work like this:

$obj = new MyClass();
$obj->funcA(); # actually calls funcA because the function
# exists in the class
$obj->funcB($a, $b); # funcB doesn't exist, so __call() gets called with
# args 'funcB', array($a, $b)
# so inside __call(), we append 'IMPL' to $name, then invoke
# $this->funcBIMPL($a, $b)

Using this setup, when I want to add a new function called mySuperFunc(), I
merely have to define mySuperFuncIMPL() and magically the wrapper is "made
for me"...=)

Thanks for the help and ideas!

Jul 19 '05 #6

P: n/a
I'm with Steven Bethard on this; I don't know what you
(Christopher J. Bottaro) are trying to do.

Based on your example, does the following meet your needs?
class Spam(object): .... def funcA(self):
.... print "A is called"
.... def __getattr__(self, name):
.... if name.startswith("_"):
.... raise AttributeError, name
.... f = get_function(name)
.... if f is not None:
.... return f
.... raise AttributeError, name
.... def get_function(name): .... return globals().get(name + "IMPL", None)
.... x = Spam()
x.funcA() A is called x.funcB() Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 10, in __getattr__
AttributeError: funcB def funcBIMPL(): .... print "Calling all bees"
.... x.funcB() Calling all bees

Confused-ly-your's

Andrew
da***@dalkescientific.com
Jul 19 '05 #7

P: n/a
Christopher J. Bottaro wrote:
I haven't tried it yet, but this is what I would do with __call():

function __call($name, $args) {
$name .= 'IMPL';
try { $this->$name($args); }
except { # error handling; }
}

function funcA() {
# do something
}

function funcBIMPL($a, $b) {
# do something
}

So I imagine it would work like this:

$obj = new MyClass();
$obj->funcA(); # actually calls funcA because the function
# exists in the class
$obj->funcB($a, $b); # funcB doesn't exist, so __call() gets called with
# args 'funcB', array($a, $b)
# so inside __call(), we append 'IMPL' to $name, then invoke
# $this->funcBIMPL($a, $b)

Using this setup, when I want to add a new function called mySuperFunc(), I
merely have to define mySuperFuncIMPL() and magically the wrapper is "made
for me"...=)


Something like this might work:

py> class C(object):
.... def func_a(self):
.... print "func_a"
.... def func_b_impl(self):
.... print "func_b"
.... raise Exception
.... def __getattr__(self, name):
.... func = getattr(self, '%s_impl' % name)
.... wrapped_func = self._impl_wrapper(func)
.... setattr(self, name, wrapped_func)
.... return wrapped_func
.... def _impl_wrapper(self, func):
.... def wrapper(*args, **kwargs):
.... try:
.... return func(*args, **kwargs)
.... except:
.... print "entered except"
.... raise
.... return wrapper
....
py> c = C()
py> c.func_a()
func_a
py> c.func_b()
func_b
entered except
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 15, in wrapper
File "<interactive input>", line 6, in func_b_impl
Exception

The idea here is that __getattr__ is called whenever the class doesn't
have a particular function. The __getattr__ method then tries to find a
corresponding _impl function, wraps it with appropriate try/except code,
and returns the wrapped function.

HTH,

STeVe
Jul 19 '05 #8

P: n/a
[Christopher J. Bottaro]
def myFunc():
print __myname__
>>> myFunc()

'myFunc'
Perhaps the __name__ attribute is what you want:

def myFunc(): print myFunc.__name__
myFunc()

myFunc

Jul 19 '05 #9

P: n/a
Christopher J. Bottaro wrote:
Steven Bethard wrote:
[...snip...]
Yes, has's suggestion is probably the right way to go here. I'm still
uncertain as to your exact setup here. Are the functions you need to
wrap in a list you have? Are they imported from another module? A
short clip of your current code and what you want it to do would help.

But I want to avoid having to write each wrapper myself. As it is now, when
I want to add a public method to my class named myFunc, I first write
myFunc which is a wrapper to the implementation:

def myFunc(self):
try: self.myFuncIMPL()
except: # error handling code

def myFuncIMPL(self):
# do the real stuff here, no need to worry about error handling stuff
# cuz its done in the wrapper

I guess I'm just lazy, but I don't want to write the wrapper func for each
new func I want to add. I want it done automatically.


You can do this almost automatically with a decorator:

def in_try(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
print "entered except"
raise
return wrapper

class C(object):
@in_try
def func_a(self):
print "func_a"

@in_try
def func_b(self):
print "func_b"
raise Exception

You could probably create a metaclass to apply the wrappers automatically but I like having it explicit as above.

Kent
Jul 19 '05 #10

P: n/a
<posted & mailed>

Hey again Steven,
I'm still having problems...

Steven Bethard wrote:
Something like this might work:

py> class C(object):
... def func_a(self):
... print "func_a"
... def func_b_impl(self):
... print "func_b"
... raise Exception
... def __getattr__(self, name):
... func = getattr(self, '%s_impl' % name)
... wrapped_func = self._impl_wrapper(func)
... setattr(self, name, wrapped_func)
... return wrapped_func
... def _impl_wrapper(self, func):
... def wrapper(*args, **kwargs):
... try:
... return func(*args, **kwargs)
... except:
... print "entered except"
... raise
... return wrapper
...
py> c = C()
py> c.func_a()
func_a
py> c.func_b()
func_b
entered except
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 15, in wrapper
File "<interactive input>", line 6, in func_b_impl
Exception

The idea here is that __getattr__ is called whenever the class doesn't
have a particular function. The __getattr__ method then tries to find a
corresponding _impl function, wraps it with appropriate try/except code,
and returns the wrapped function.
The problem is:
c.func_b.__name__

'wrapper'

That messes up SOAPpy's RegisterFunction() method which apparently depends
on the __name__ of the function to publish it as an available SOAP
function.

Any suggestions on how to change the name of c.func_b to 'func_b' instead of
'wrapper'?
HTH,
STeVe


Thanks a bunch,
-- C

Jul 19 '05 #11

P: n/a
Christopher J. Bottaro wrote:
Steven Bethard wrote:
... def _impl_wrapper(self, func):
... def wrapper(*args, **kwargs):
... try:
... return func(*args, **kwargs)
... except:
... print "entered except"
... raise
... return wrapper
... [snip]

The problem is:
c.func_b.__name__


'wrapper'

That messes up SOAPpy's RegisterFunction() method which apparently depends
on the __name__ of the function to publish it as an available SOAP
function.


Hmm... Nasty. If you were using Python 2.4, you could simply write it as:

def _impl_wrapper(self, func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
print "entered except"
raise
wrapper.__name__ = func.__name__
return wrapper

Where you fix up the wrapper's __name__ attribute. But I believe the
__name__ attribute is read-only in Python 2.3...

STeVe
Jul 19 '05 #12

P: n/a
<posted & mailed>

Christopher J. Bottaro wrote:
The problem is:
c.func_b.__name__

'wrapper'

That messes up SOAPpy's RegisterFunction() method which apparently depends
on the __name__ of the function to publish it as an available SOAP
function.

Any suggestions on how to change the name of c.func_b to 'func_b' instead
of 'wrapper'?


Nevermind, I looked at the SOAPpy source, they provide a way to manually
specify the SOAP method name that is published.

Thanks anyways,
-- C

Jul 19 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.