在Python中调用嵌套函数

2024-05-20 18:44:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个方法,我已经分解成更小的嵌套函数来分解代码基:

def foo(x,y):
    def do_this(x,y):
        pass
    def do_that(x,y):
        pass
    do_this(x,y)
    do_that(x,y)
    return

有没有办法自己运行一个嵌套函数。例如:

foo.do_this(x,y)

编辑:

我正在尝试在我用金字塔破坏者构建的web服务器上设置缓存

def getThis(request):
    def invalidate_data(getData,'long_term',search_term):
         region_invalidate(getData,'long_term',search_term)
    @cached_region('long_term')
    def getData(search_term):
         return response
    search_term = request.matchdict['searchterm']
    return getData(search_term)

我的理解可能不准确:

现在我这样做的原因是decorator用来创建缓存键的名称空间是从函数和参数中生成的。因此,不能只将decorator放在getThis上,因为请求变量是唯一的,而缓存是无用的。所以我创建了具有可重复参数(search_term)的内部函数。

但是要使缓存失效(即刷新),失效函数需要作用域知道“getData”函数,因此也需要嵌套。因此我需要调用嵌套函数。你们这些了不起的人已经明确表示这是不可能的,所以有人能解释我如何用不同的结构来做吗?


Tags: 函数searchreturnthatfoorequestdefpass
3条回答

这些之前的回答,告诉你你不能这样做,当然是错误的。 这是python,你可以用一些魔术代码做任何你想做的事情。

我们可以从foo的函数代码中取出第一个常量,这将是do_this函数。然后我们可以使用这段代码创建一个新的函数。

有关new的详细信息,请参见https://docs.python.org/2/library/new.html;有关如何获取内部代码的详细信息,请参见https://docs.python.org/2/library/inspect.html

警告:不是因为你能做到这一点,你才应该这样做, 重新思考你的功能结构是一个可行的方法,但是如果你想要一个在未来可能会崩溃的快速而肮脏的黑客,你可以这样做:

import new
myfoo = new.function(foo.func_code.co_consts[1],{}) 
myfoo(x,y) # hooray we have a new function that does what I want

更新:在python3中,可以将types模块与foo.__code__一起使用:

import types
myfoo = types.FunctionType(foo.__code__.co_consts[1], {})
myfoo()  # behaves like it is do_this()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: do_this() missing 2 required positional arguments: 'x' and 'y'

我假设do_thisdo_that实际上依赖于foo的某个参数,否则您可以将它们移出foo并直接调用它们。

我建议把整件事作为一节课来复习。像这样的:

class Foo(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def do_this(self):
        pass

    def do_that(self):
        pass

    def __call__(self):
        self.do_this()
        self.do_that()

foo = Foo(x, y)
foo()
foo.do_this()

不,没有。因为您可以从嵌套函数中访问外部作用域中的变量:

def foo(x,y):
    def do_this(z):
        print(x,y,z)
    # ...

在为xy提供绑定时,无法调用do_this

如果必须从其他地方调用do_this,只需将其设置为与foo处于同一级别的顶级函数。

相关问题 更多 >