Dynamically altering __init__

Ian Kelly ian.g.kelly at gmail.com
Thu Oct 13 13:14:23 EDT 2011


2011/10/13 Kääriäinen Anssi <anssi.kaariainen at thl.fi>:
> import parser
> import types
> st = parser.suite(src)
> dyn_func = parser.compilest(st)
> f = types.FunctionType(dyn_func, {}, '__init__')
> im = types.MethodType(f, None, Foo)
> Foo()
> Foo.__init__ = im
> Foo(1, 2, 3)
>
> The result is: TypeError: <module>() takes no arguments (4 given). I have
> figured out that when I call f(), I am actually executing the src as is, not
> the defined function in the src. But I can't figure out how to get a
> reference to my_init_func.

You can either pull the function code object out of the module code
object constants:

...
st_code = parser.compilest(st)
func_code = st_code.co_consts[0]
f = types.FunctionType(func_code, {}, '__init__')
...

But you should take care to ensure that the function code object
actually is the first constant.  Or you can just exec your suite and
pull the function from its globals.

src_globals = {}
exec src in src_globals
my_init_func = src_globals['my_init_func']

Cheers,
Ian



More information about the Python-list mailing list