Given the function
def f():
x, y = 1, 2
def get():
print \'get\'
def post():
print \'post\'
is there a way for
The inner function objects don't exist before the function f() is executed. If you want to get them you'll have to construct them yourself. That is definitely non-trivial because they might be closures that capture variables from the scope of the function and will anyway require poking around in objects that should probably be regarded as implementation details of the interpreter.
If you want to collect the functions with less repetition I recommend one of the following approaches:
a) Just put the functions in a class definition and return a reference to that class. A collection of related functions that are accessed by name smells awfully like a class.
b) Create a dict subclass that has a method for registering functions and use that as a decorator.
The code for this would look something like this:
class FunctionCollector(dict):
def register(self, func):
self[func.__name__] = func
def f():
funcs = FunctionCollector()
@funcs.register
def get():
return 'get'
@funcs.register
def put():
return 'put'
return funcs
c) Poke around in locals() and filter out the function with inspect.isfunction. (usually not a good idea)
You can return functions just like any other object in Python:
def f():
x, y = 1, 2
def get():
print 'get'
def post():
print 'post'
return (get, post)
get, post = f()
Hope this helps!
Note, though, that if you want to use your 'x' and 'y' variables in get() or post(), you should make them a list.
If you do something like this:
def f():
x = [1]
def get():
print 'get', x[0]
x[0] -= 1
def post():
print 'post', x[0]
x[0] += 1
return (get, post)
get1, post1 = f()
get2, post2 = f()
get1 and post1 will reference a different 'x' list than get2 and post2.
You are pretty close of doing that - just missing new
module:
import inspect
import new
def f():
x, y = 1, 2
def get():
print 'get'
def post():
print 'post'
for c in f.func_code.co_consts:
if inspect.iscode(c):
f = new.function(c, globals())
print f # Here you have your function :].
But why the heck bother? Isn't it easier to use class? Instantiation looks like a function call anyway.
You could use exec to run the code objects. For example, if you had f defined as above, then
exec(f.func_code.co_consts[3])
would give
get
as output.