inspect feature

Aaron "Castironpi" Brady castironpi at gmail.com
Fri Oct 10 19:18:53 CEST 2008


On Oct 10, 3:36 am, Bruno Desthuilliers <bruno.
42.desthuilli... at websiteburo.invalid> wrote:
> Aaron "Castironpi" Brady a écrit :
>
>
>
> > On Oct 9, 3:48 am, Bruno Desthuilliers <bruno.
> > 42.desthuilli... at websiteburo.invalid> wrote:
> >> Aaron "Castironpi" Brady a écrit :
>
> >>> Hello,
> >>> The 'inspect' module has this method:
> >>> inspect.getargvalues(frame)
> >>> It takes a frame and returns the parameters used to call it, including
> >>> the locals as defined in the frame, as shown.
> >>>>>> def f( a, b, d= None, *c, **e ):
> >>> ...     import inspect
> >>> ...     return inspect.getargvalues( inspect.currentframe() )
> >>> ...
> >>>>>> f( 0, 1, 'abc', 'def', ( 3, 2 ), h= 'ghi' )
> >>> (['a', 'b', 'd'], 'c', 'e', {'a': 0, 'c': ('def', (3, 2)), 'b': 1,
> >>> 'e': {'h': 'g
> >>> hi'}, 'd': 'abc', 'inspect': <module 'inspect' from 'C:\Programs
> >>> \Python26\lib\in
> >>> spect.pyc'>})
> >>> However, if you wanted a decorator that examines the parameters to a
> >>> function, you're out of luck.  By the time you have a frame, you're
> >>> already in the function.
> >> Hem...
>
> >> def decorator(func):
> >>      def _decorator(*args, *kw):
> >>          print "func args are ", *args, **kw
> >>          return func(*args, **kw)
> >>      return _decorator
>
> > It is less of a problem without tuple unpacking, but you still have
> > code like:
>
> > if len( args )>= 2:
> >    b= args[ 1 ]
> > else:
> >    try:
> >       b= (somehow check b's default val.)
> >    except NoDefaultVal:
> >       raise ArgumentError
>
> > Worse yet, you have it for each parameter.  Unless I missed something,
> > this is the only way to mimic/recreate the signature of the decoratee.
>
> I don't get what you're after ??? The decorator has full access to both
> the actual params *and* the function's signature (via
> inspect.getargspec). So your initial question "if you wanted a decorator
> that examines the parameters to a function" seems fully answered. You
> will indeed have to write a couple lines of code if you want the same
> formating as the one you'd get with inspect.currentframe(), but what ?
>
> FWIW, Michele Simionato's decorator module has some trick to allow for
> signature-preserving decorators, so you may want to have a look - but
> I'm not sure if this would solve your problem - at least in a sane way.

It's not exactly the next Millennium problem, but there are some
substantial checks you have to do on a per-parameter basis to see the
same thing that a function sees, when all you have is *args, **kwargs.

You are wrapping a function with this signature:

def f( a, b, c= None, *d, **e ):

You want to find out the values of 'a', 'b', and 'c' in a decorator.
You have these calls:

f( 0, 1, 'abc', 'def', h= 'ghi' )
f( 0, 1 )
f( 0, 1, h= 'abc' )
f( 0, 1, 'abc', c= 'def' ) #raise TypeError: multiple values

How do you determine 'a', 'b', and 'c'?



More information about the Python-list mailing list