Python: 从 outer() 调用 inner()

Python: calling inner() from outer()

我环顾四周,令人惊讶的是没有找到这个问题的答案。我认为这是因为通常 inner/nested 函数用于某些特定的事情(例如维护环境变量、工厂),而不是像我试图将它们用于某些琐碎的事情。无论如何,我似乎找不到任何关于如何从外部函数正确调用内部函数而不必在文件中的 outer() 上方声明 inner() 的信息。问题来自 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

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

因为一个函数是从上到下执行的,一个函数是随着函数的处理而存在的,你想要的是不可能的。

你可以把函数放在外层函数之前,使它成为外层函数,可能会添加一些参数(这里不需要)。 (顺便说一句,它看起来非常通用,代码的其他部分可能也想使用它,所以为什么不在外部呢?)

否则,你就卡住了。它与

中的情况基本相同
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()

但我看不出你有什么收获。

这在 Python 中是不可能的,但在 Javascript 和 PHP 等其他语言中是可能的。它被称为函数提升。