Functions and code objects

Simon Forman rogue_pedro at yahoo.com
Thu Jul 27 10:43:04 EDT 2006


Fuzzyman wrote:
> Fuzzyman wrote:
> > Fuzzyman wrote:
> > > Hello all,
> > >
> > > I'm trying to extract the code object from a function, and exec it
> > > without explicitly passing parameters.
> > >
> > > The code object 'knows' it expects to receive paramaters. It's
> > > 'arg_count' attribute is readonly.
> > >
> > > How can I set the arg_count to 0, or pass parameters to the code object
> > > when I exec it ?
> > >
> >
> > Ok, so now I'm getting somewhere, without really knowing what I'm
> > doing. Using the CodeType I can create a new code object with identical
> > attributes, except an 'argcount' of 0.
> >
> > It doesn't quite work, so I probably need to set some of the attributes
> > *differently*.
> >
> > The code I use is :
> >
> > >>> def f(x):
> >  ...     print x
> >  ...
> > >>> c = f.func_code
> > >>> CodeType = type(c)
> > >>> a = CodeType(0, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_code,
> >  ...     c.co_consts, c.co_names, c.co_varnames, c.co_filename,
> > c.co_name,
> >  ...     c.co_firstlineno, c.co_lnotab, c.co_freevars, c.co_cellvars)
> > >>> a
> > <code object f at 01C707A0, file "<input>", line 1>
> > >>> exec a
> > Traceback (most recent call last):
> >   File "<input>", line 1, in ?
> >   File "<input>", line 2, in f
> > UnboundLocalError: local variable 'x' referenced before assignment
> >
> > (the first argument, 0, becomes the 'arg_count' attribute)
> >
> > So the code object is still creating a local scope, and knows that x is
> > a local variable. ('co_nlocals' and 'co_varnames' ?).
> >
> > I'd like to construct the code object so that it takes the parameters
> > from the enclosing scope (the context I pass into exec I guess),
> > without clobbering any local variables that may be defined in the code
> > object.
> >
> > Anyone got any clues ?
> >
>
> *Damn* I've extracted the code object and told it that it has no
> arguments. Executing the code object results in the function object !
>
> The code object is obviously the code object for the function
> definition. *sigh*
>
> I was hoping I could get to the code object for the *body* of the
> function. Looks like that won't be possible without dis-assembling the
> bytecode or other tricks even more hackish than what I've already done.
>
> For the record, the code  I was using was :
>
> x = 3
> def f(x):
>     print x
>
> CodeType = type(f.func_code)
>
> def convert_function(f):
>     code = f.func_code
>     nlocals = max(code.co_nlocals - code.co_argcount, 0)
>     newCode = CodeType(0, nlocals, code.co_stacksize, code.co_flags,
>                        code.co_code, code.co_consts, code.co_names,
>                        code.co_varnames, code.co_filename,
> code.co_name,
>                        code.co_firstlineno, code.co_lnotab,
> code.co_freevars,
>                        code.co_cellvars)
>     return newCode
>
> print convert_function(f)
> exec convert_function(f)
>
> Fuzzyman
> http://www.voidspace.org.uk/python/index.shtml

Out of curiosity, why are you doing this?

Peace,
~Simon




More information about the Python-list mailing list