Get actual call signature?
Hans Georg Krauthäuser
hgk at ieee.org
Wed Mar 19 04:26:32 EDT 2008
On 18 Mrz., 11:40, Jarek Zgoda <jzg... at o2.usun.pl> wrote:
> Say, I have a function defined as:
>
> def fun(arg_one, arg_two='x', arg_three=None):
> pass
>
> Is there any way to get actual arguments that will be effectively used
> when I call this function in various ways, like:
>
> fun(5) => [5, 'x', None]
> fun(5, arg_three=['a', 'b']) => [5, 'x', ['a', 'b']]
> fun(5, 'something') => [5, 'something', None]
>
> (et caetera, using all possible mixes of positional, keyword and default
> arguments)
>
> I'd like to wrap function definition with a decorator that intercepts
> not only passed arguments, but also defaults that will be actually used
> in execution.
>
> If this sounds not feasible (or is simply impossible), I'll happily
> throw this idea and look for another one. ;)
>
> --
> Jarek Zgoda
> Skype: jzgoda | GTalk: zg... at jabber.aster.pl | voice: +48228430101
>
> "We read Knuth so you don't have to." (Tim Peters)
Perhaps like so:
import inspect
class CLS(object):
def fun(self, arg_one, arg_two='x', arg_three=None):
print get_signature(self)
def get_signature(obj):
frame = inspect.currentframe()
outerframes = inspect.getouterframes(frame)
caller = outerframes[1][0]
try:
args, varargs, varkw, loc = inspect.getargvalues(caller)
allargs = args
allargs.pop(0) # self
if not varargs is None:
allargs += varargs
if not varkw is None:
allargs += varkw
sdict={}
for arg in allargs:
sdict[arg]=caller.f_locals[arg]
ccframe = outerframes[2][0]
ccmodule = inspect.getmodule(ccframe)
try:
slines, start = inspect.getsourcelines(ccmodule)
except:
clen = 100
else:
clen = len(slines)
finfo = inspect.getframeinfo(ccframe, clen)
theindex = finfo[4]
lines = finfo[3]
theline = lines[theindex]
cmd = theline
for i in range(theindex-1, 0, -1):
line = lines[i]
try:
compile (cmd.lstrip(), '<string>', 'exec')
except SyntaxError:
cmd = line + cmd
else:
break
finally:
del frame
del outerframes
del caller
del ccframe
return cmd, sdict
if __name__ == '__main__':
c=CLS()
c.fun(5)
c.fun(5, arg_three=['a', 'b'])
c.fun(5, 'something')
c.fun(5,
'something')
a=c.fun
a(4)
Best Regards
Hans Georg
More information about the Python-list
mailing list