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 -- http://mail.python.org/mailman/listinfo/python-list