3

Possible Duplicate:
How to pass arguments to the __code__ of a function?

I have a code object representing a function. When I call exec on the code object, how do I specify a value for the input parameter p?

def x(p):
    print p

code_obj = x.__code__

exec code_obj
#TypeError: x() takes exactly 1 argument (0 given)
martineau
  • 119,623
  • 25
  • 170
  • 301
iancoleman
  • 2,766
  • 2
  • 19
  • 17
  • thankyou, wish my search skills were better. – iancoleman Jun 21 '12 at 10:02
  • 1
    Though the best solution is worth to mention here too: `import types; types.FunctionType(code_obj, {})(1)` (because it exists only as a comment, and not even for the accepted answer) – mutantacule Jun 21 '12 at 10:21
  • 2
    indeed, I saw that technique and used it in a test which worked well. Ultimately I have heeded the wise words to avoid using __code__ wherever possible and use __import__ instead. But it's an interesting curiosity which has now been satisfied. – iancoleman Jun 21 '12 at 10:29
  • 2
    @kosii If the best answer isn't an answer, I suggest you add it as one. – Gareth Latty Jun 21 '12 at 10:47

1 Answers1

1

Resuming the answers and comments from the duplicated:

import types
types.FunctionType(code_obj, globals={}, name='x')(1)

To work with methods, you can use a function type or an unbound method and then pass an instance as first parameter, or bound the function to an instance:

class A(object):
    def __init__(self, name):
        self.name = name
    def f(self, param):
        print self.name, param

# just pass an instance as first parameter to a function or to an unbound method
func = types.FunctionType(A.f.__code__, globals={}, name='f')
func(A('a'), 2)
unbound_method = types.MethodType(func, None, A)
unbound_method(A('b'), 3)
# or bound the function to an instance
bound_method = types.MethodType(func, A('c'), A)
bound_method(4)
mutantacule
  • 6,913
  • 1
  • 25
  • 39
  • Can you please explain the benefit of adding name='x' in the call (your first code block)? I ran this without the name parameter and it worked fine. What's the incentive to have that parameter there? – iancoleman Jun 21 '12 at 13:35
  • It's an optional parameter, I just wanted to show it. It's used for example when you print a function object. – mutantacule Jun 21 '12 at 13:42