Python:从external()调用inner()

时间:2018-10-26 07:49:42

标签: python function-call nested-function

我四处寻找SO,但是令人惊讶的是没有找到这个问题的答案。我认为这是因为通常将内部/嵌套函数用于某些特定的事物(例如,维护环境变量,工厂),而不是像我试图将其用于琐碎的事物。无论如何,我似乎都无法找到有关如何从外部函数正确调用内部函数的任何信息,而不必在文件中的inner()上方声明outer()。问题出在HackerRank(https://www.hackerrank.com/challenges/circular-array-rotation/problem)上。

def circularArrayRotation(a, k, queries):

    def rotateArrayRightCircular(arr: list, iterations: int) -> list:
        """
        Perform a 'right circular rotation' on an array for number of iterations.
        Note: function actually moves last 'iterations' elements of array to front of array.

        >>>rotateArrayRightCircular([0,1,2], 1)
        [2,0,1]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
        [3,4,5,0,1,2]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
        [0,1,2,3,4,5]
        """
        return arr[-1 * iterations:] + arr[0:-1 * iterations]

    k = k % len(a)
    a = rotateArrayRightCircular(a, k)
    res = []
    for n in queries:
        res.append(a[n])
    return res

上面的代码可以实现我想要的功能,但是对于我来说,必须将内部函数调用放在内部函数定义之后,这对我来说有点不明智。尝试不同的各种错误:

# trying 'self.inner()'
Traceback (most recent call last):
  File "solution.py", line 52, in <module>
    result = circularArrayRotation(a, k, queries)
  File "solution.py", line 13, in circularArrayRotation
    a = self.rotateArrayRightCircular(a, k)
NameError: name 'self' is not defined

# Removing 'self' and leaving the definition of inner() after the call to inner()
Traceback (most recent call last):
  File "solution.py", line 52, in <module>
    result = circularArrayRotation(a, k, queries)
  File "solution.py", line 13, in circularArrayRotation
    a = rotateArrayRightCircular(a, k)
UnboundLocalError: local variable 'rotateArrayRightCircular' referenced before assignment

您知道如何在对def inner()的调用之后包含inner() 而不会引发错误吗?

2 个答案:

答案 0 :(得分:2)

由于函数是从上到下执行的,并且随着函数的处理而存在,所以想要的只是不可能的。

您可以将函数放在外部函数之前,使其本身在外部,可能添加一些参数(此处不必要)。 (顺便说一句,它看起来是如此通用,代码的其他部分也可能想要使用它,所以为什么不使用外部代码呢?)

但是,否则,您将陷入困境。基本上与

中的情况相同
def f():
    print(a) # a doesn't exist yet, so this is an error
    a = 4

好吧,你可以这样:

def circularArrayRotation(a, k, queries):

    def inner_code():
        k = k % len(a)
        a = rotateArrayRightCircular(a, k)

        # BTW, instead of the following, you could just do
        # return [a[n] for n in queries]
        res = []
        for n in queries:
            res.append(a[n])
        return res


    def rotateArrayRightCircular(arr: list, iterations: int) -> list:
        """
        Perform a 'right circular rotation' on an array for number of iterations.
        Note: function actually moves last 'iterations' elements of array to front of array.

        >>>rotateArrayRightCircular([0,1,2], 1)
        [2,0,1]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
        [3,4,5,0,1,2]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
        [0,1,2,3,4,5]
        """
        return arr[-1 * iterations:] + arr[0:-1 * iterations]

    return inner_code()

但是我看不到你从中得到任何好处。

答案 1 :(得分:1)

这在Python中是不可能的,但是在其他语言(例如Javascript和PHP)中是可能的。这称为功能提升。