访问函数内的函数(嵌套函数?)

时间:2011-08-14 00:40:57

标签: python

Python noob在这里。 如何在'fib'函数中掌握'内部'函数?

from time import sleep

class Fibonacci(object):

    def __init__(self, a, b, limit=50):
        self.a = a
        self.b = b
        self.limit = limit

    def fib(self):

        while self.a < self.limit:
            c = self.a + self.b
            sleep(1)
            print self.a,
            self.b = self.a
            self.a = c

        def inner(self):
            print 'Damn it! Just print already!'


j = Fibonacci(0,1,2)
j.fib()

## This doesn't work. Gives an "AttibuteError: 'function' object has no attribute 'inner'"
j.fib.inner()

5 个答案:

答案 0 :(得分:11)

除非fib以某种方式返回inner,否则你不能这样做。 inner本质上是fib范围内的局部变量,您无法从其外部访问函数的本地变量。 (这甚至没有意义,因为除了函数运行时本地人不存在。想一想 - 从外部访问fib的{​​{1}}变量是否有意义功能?)

答案 1 :(得分:8)

请勿使用以下内容。

[...]
>>> j = Fibonacci(0,1,2) 
>>> j.fib()
0 1 1
>>> # dark magic begins!
>>> import new
>>> new.function(j.fib.im_func.func_code.co_consts[2],{})(None)
Damn it! Just print already!

你可以简单地看一下,它不是真正的Python,而且就其本身并没有真正调用“内部”函数,它只是创建一个类似它的新函数。我也没有打扰设置全局'正确',因为这首先是一件可怕的事情。

[我应该提到的是,上述要点是要注意,你不能从外部访问内部的想法并不严格,尽管这几乎不是一个好主意。例外情况包括口译员级别的代码检查等。]

不洁净!不洁!

答案 2 :(得分:5)

from time import sleep

class Fibonacci(object):

    def __init__(self, a, b, limit=50):
        self.a = a
        self.b = b
        self.limit = limit

    def fib(self):

        while self.a < self.limit:
            c = self.a + self.b
            sleep(1)
            print self.a,
            self.b = self.a
            self.a = c

        def inner(self):
            print 'Damn it! Just print already!'
        Fibonacci.fib.inner = inner

    fib.inner = None

此代码段允许您使用内部。

答案 3 :(得分:4)

以下似乎达到了你想要的效果

from types import CodeType, FunctionType

def find_nested_func(parent, child_name):
    """ Return the function named <child_name> that is defined inside
        a <parent> function
        Returns None if nonexistent
    """
    consts = parent.func_code.co_consts
    for item in consts:
        if isinstance(item, CodeType) and item.co_name==child_name:
            return FunctionType(item, globals())

答案 4 :(得分:1)

正如其他一些读者所说,这是一个范围问题。 FWIW,这是通过返回内部函数来实现的:

from time import sleep

class Fibonacci(object):

    def __init__(self, a, b, limit=50):
        self.a = a
        self.b = b
        self.limit = limit

    def fib(self):

        while self.a < self.limit:
            c = self.a + self.b
            sleep(1)
            print self.a,
            self.b = self.a
            self.a = c

        def inner():
            print 'Damn it! Just print already!'

        return inner


j = Fibonacci(0,1,2)
j.fib()()

作为参考,这里有一个很好的介绍python的范围:

Short Description of the Scoping Rules?