在Python中检查给定函数的嵌套(局部)函数

5 投票
4 回答
2511 浏览
提问于 2025-04-15 13:24

给定这个函数

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

但是我不知道怎么才能拿到真正可以调用的函数对象。这可能吗?

谢谢你的帮助,

Will。

4 个回答

2

你可以使用exec来运行代码对象。比如,如果你像上面那样定义了f,那么

exec(f.func_code.co_consts[3])

就会输出

get

的结果。

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会引用一个不同的'x'列表,而get2和post2会引用另一个。

6

你已经快做到这一点了,只是缺少了 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 :].

但是为什么要这么麻烦呢?用类不是更简单吗?反正实例化看起来就像是调用一个函数。

撰写回答