鉴于功能
def f():
x, y = 1, 2
def get():
print 'get'
def post():
print 'post'
我有办法以我可以调用它们的方式访问其本地get()和post()函数吗?我正在寻找一个可以使用上面定义的函数f()的函数:
>>> get, post = get_local_functions(f)
>>> get()
'get'
我可以访问像这样的本地函数的代码对象
import inspect
for c in f.func_code.co_consts:
if inspect.iscode(c):
print c.co_name, c
导致
get <code object get at 0x26e78 ...>
post <code object post at 0x269f8 ...>
但我无法弄清楚如何获取实际的可调用函数对象。这甚至可能吗?
感谢您的帮助,
威尔
答案 0 :(得分:4)
你已经非常接近了 - 只是缺少new
模块:
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 :].
但为什么麻烦呢?使用课程不是更容易吗?无论如何,实例化看起来像一个函数调用。
答案 1 :(得分:2)
您可以像在Python中的任何其他对象一样返回函数:
def f():
x, y = 1, 2
def get():
print 'get'
def post():
print 'post'
return (get, post)
get, post = f()
希望这有帮助!
但请注意,如果要在get()或post()中使用'x'和'y'变量,则应将它们作为列表。
如果您这样做:
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和post1将引用与get2和post2不同的“x”列表。
答案 2 :(得分:2)
您可以使用exec来运行代码对象。例如,如果你有如上定义的f,那么
exec(f.func_code.co_consts[3])
会给出
get
作为输出。
答案 3 :(得分:1)
在执行函数f()之前,内部函数对象不存在。如果你想得到它们,你必须自己构建它们。这绝对是不重要的,因为它们可能是从函数范围捕获变量的闭包,无论如何都需要在对象中进行调整,这些对象应该被视为解释器的实现细节。
如果您想以较少的重复收集功能,我建议采用以下方法之一:
a)只需将函数放在类定义中并返回对该类的引用。通过名称访问的相关函数的集合闻起来像一个类。
b)创建一个dict子类,它有一个注册函数的方法并将其用作装饰器。
这个代码看起来像这样:
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)在locals()中查找并使用inspect.isfunction过滤掉该函数。 (通常不是一个好主意)