5

给定函数

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 ...>

但我不知道如何获取实际的可调用函数对象。这甚至可能吗?

谢谢你的帮助,

将要。

4

4 回答 4

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 :].

但是为什么要麻烦呢?使用类不是更容易吗?无论如何,实例化看起来像一个函数调用。

于 2009-08-05T21:15:39.100 回答
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”列表。

于 2009-08-05T17:43:38.137 回答
2

您可以使用 exec 来运行代码对象。例如,如果你有 f 如上定义,那么

exec(f.func_code.co_consts[3])

会给

get

作为输出。

于 2009-08-05T17:57:21.310 回答
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 过滤掉函数。(通常不是一个好主意)

于 2009-08-05T20:45:10.317 回答