python之 Nested Function

python之 Nested Function

好文转载 What is a Nested Function? ​https://zhuanlan.zhihu.com/p/53116610【译文稍作修改】

Functions are one of the "first-class citizens" of Python, which means that functions are at the same level as other Python objects like integers, strings, modules, etc. They can be created and destroyed dynamically, passed to other functions, returned as values, etc.
函数是 Python 的“一等公民”之一,这意味着函数与其他 Python 对象(如整数、字符串、模块等)处于同一级别。 它们可以动态地创建和销毁,传递给其他函数,作为值返回,等等。


Python supports the concept of a "nested function" or "inner function", which is simply a function defined inside another function. In the rest of the article, we will use the word "inner function" and "nested function" interchangeably.
Python 支持“嵌套函数(nested function)”或“内部函数(inner function)”的概念,它只是在另一个函数中定义的一个函数。 在本文的其余部分,我们将交替使用"inner function"和"nested function"这两个词。


There are various reasons as to why one would like to create a function inside another function. The inner function is able to access the variables within the enclosing scope. In this article, we will be exploring various aspects of inner functions in Python.
对于为什么要在另一个函数中创建一个函数,有各种各样的原因。 内部函数能够访问封闭范围内的变量。 在本文中,我们将探索 Python 内部函数的各个方面。


Defining an Inner Function
定义内部函数


To define an inner function in Python, we simply create a function inside another function using the Python's def keyword. Here is an example:
为了在 Python 中定义一个内部函数,我们只需使用 Python 的 def 关键字在另一个函数中创建一个函数。 下面是一个例子:

def function1(): # outer function  
    print ("Hello from outer function")
    def function2(): # inner function
        print ("Hello from inner function")
    function2()

function1()  

Output
输出

Hello from outer function
Hello from inner function


In the above example, function2() has been defined inside function1(), making it an inner function. To call function2(), we must first call function1(). The function1() will then go ahead and call function2() as it has been defined inside it.
在上面的示例中,function2()是在 function1()内部定义的,因此它是一个内部函数。 要调用 function2() ,我们必须先调用 function1()。 然后,function1()将继续调用在其中定义的 function2()。


It is important to mention that the outer function has to be called in order for the inner function to execute. If the outer function is not called, the inner function will never execute. To demonstrate this, modify the above code to the following and run it:
必须指出的是,为了执行内部函数,必须调用外部函数。 如果不调用外部函数,内部函数将永远不会执行。 为了演示这一点,将上面的代码修改为下面的代码并运行它:

def function1(): # outer function  
    print ("Hello from outer function")
    def function2(): # inner function
        print ("Hello from inner function")
    function2()

#function1() 

The code will return nothing when executed!
代码在执行时将不返回任何内容!
 

Here is another example:
下面是另一个例子:

def num1(x):  
   def num2(y):
      return x * y
   return num2
res = num1(10)

print(res(5)) 

Output
输出

50

The code returns the multiplication of the two numbers, that is, 10 and 5. The example shows that an inner function is able to access variables accessible in the outer function.
该代码返回两个数字的相乘,即10和5。 该示例表明,内部函数能够访问外部函数中可访问的变量。


So far, you have seen that it is possible for us to access the variables of the outer function inside the inner function. What if we attempt to change the variables of the outer function from inside the inner function? Let us see what happens:
到目前为止,您已经看到,我们可以访问内部函数中外部函数的变量。 如果我们尝试从内部函数改变外部函数的变量呢? 让我们看看会发生什么:

def function1(): # outer function  
    x = 2 # A variable defined within the outer function
    def function2(a): # inner function
       # Let's define a new variable within the inner function
       # rather than changing the value of x of the outer function
        x = 6
        print (a+x)
    print (x) # to display the value of x of the outer function
    function2(3)

function1()  

Output
输出

2
9

The output shows that it is possible for us to display the value of a variable defined within the outer function from the inner function, but not change it. The statement x = 6 helped us create a new variable x inside the inner function function2() rather than changing the value of variable xdefined in the outer function function1().
输出表明,我们可以从内部函数显示在外部函数中定义的变量的值,但不改变它。 x=6语句帮助我们在内部函数 function2()中创建一个新的变量 x,而不是更改在外部函数 function1()中定义的变量 x 的值。


In the next section, we will be discussing the main reasons as to why we use inner functions in Python.
在下一节中,我们将讨论在 Python 中使用内部函数的主要原因。
 

Why use Inner Functions?
为什么要使用内部函数?
 

Encapsulation
封装


A function can be created as an inner function in order to protect it from everything that is happening outside of the function. In that case, the function will be hidden from the global scope. Here is an example:
可以创建一个函数作为内部函数,以保护它不受函数之外发生的任何事情的影响。 在这种情况下,函数将被隐藏在全局作用域(global scope)之外。 下面是一个例子:

def outer_function(x):  
    # Hidden from the outer code
    def inner_increment(x):
        return x + 2
    y = inner_increment(x)
    print(x, y)

inner_increment(5)  
#outer_function(5)

Output
输出

Traceback (most recent call last): 
     File "C:/Users/admin/inner.py", line 7, in <module>
     inner_increment(5)
NameError: name 'inner_increment' is not defined


In the above code, we are trying to call the inner_increment() function, but instead we got an error.
在上面的代码中,我们试图调用内部的 increment() 函数,但是得到了一个错误。


Now, comment out the call to inner_increment() and uncomment the call to outer_function()as shown below:
现在,注释掉对 inner increment() 的调用,取消对 outer function() 的调用,如下所示:

def outer_function(x):  
    # Hidden from the outer code
    def inner_increment(x):
        return x + 2
    y = inner_increment(x)
    print(x, y)

#inner_increment(5)
outer_function(5)  

Output
输出

5 7


The script above shows that the inner function, that is, inner_increment() is protected from what is happening outside it since the variable x inside the inner_increment function is not affected by the value passed to the parameter x of the outer function. In other words, the variables inside the inner function is not accessible outside it. There is a great advantage with such a design pattern. After checking all arguments in the outer function, we can safely skip error checking within the inner function.
上面的脚本显示了内部函数,即 inner_increment() 受到保护,不受外部函数的影响,因为内部增量函数中的变量 x 不受传递给外部函数的参数 x 的值的影响。 换句话说,内部函数中的变量在外部是不可访问的。 这样的设计模式有很大的优势。 在检查了外部函数中的所有参数之后,我们可以安全地跳过内部函数中的错误检查。


Closures and Factory Functions
闭包和工厂功能


All the examples we have seen till now just contain ordinary functions that have been nested inside other functions. It is possible for us to write such functions in another way instead of nesting them inside other functions. We don't have a specific reason as to why we should nest them.
到目前为止,我们看到的所有例子都只包含嵌套在其他函数中的普通函数。 我们可以用另一种方式编写这样的函数,而不是将它们嵌套在其他函数中。 我们没有一个具体的原因,为什么我们应该嵌套他们。


However, for the case of closures, one must use the nested functions.
但是,对于闭包,必须使用嵌套函数。


We can bind/pass data to a function without necessarily passing the data to the function via parameters. This is done using a closure. It is a function object that is able to remember values in the enclosing scopes even when they are not available in the memory. This means that we have a closure when a nested function references a value that is in its enclosing scope.
我们可以将数据绑定 / 传递给函数,而不必通过参数将数据传递给函数。 这是通过闭包完成的。 它是一个函数对象,即使在内存中不可用的情况下,它也能够记住enclosing scopes(外层/封闭作用域)中的值。 这意味着当嵌套函数引用enclosing scopes内的值时,我们有一个闭包(closure)。

The purpose of a closure is to make the inner function remember the state of its environment when it is called, even if it is not in the memory. A closure is caused by an inner function, but it's not the inner function. The closure works by closing the local variable on the stack, which stays around after the creation of the stack has finished executing.
闭包(closure)的目的是使内部函数在被调用时记住其环境的状态,即使它不在内存中。 闭包是由内部函数引起的,但它不是内部函数。 闭包的工作方式是关闭(closing)堆栈上的局部变量,这个局部变量在堆栈创建完成后仍然保留。


The following are the conditions that are required to be met in order to create a closure in Python:
以下是在 Python 中创建闭包所需满足的条件:

  • There must be a nested function 。

必须有一个嵌套函数。

  • The inner function has to refer to a value that is defined in the enclosing scope。

内部函数必须引用在enclosing scope(外层/封闭作用域)中定义的值。

  • The enclosing function has to return the nested function。

enclosing function(外层/封闭函数)必须返回嵌套函数。

Consider the following example:
考虑下面的例子:

def function1(name):  
    def function2():
        print('Hello ' + name)
    return function2

func = function1('Nicholas')  
func()  

Output
输出

Hello Nicholas


The above code demonstrates that with closures, we are able to generate and invoke a function from outside its scope via function passing. The scope of function2() is only inside function1(). However, with the use of closures, it was possible for us to extend this scope and invoke it from outside its scope.
上面的代码演示了使用闭包,我们能够通过函数传递从其作用域之外生成和调用函数。 Function2()的作用域仅在 function1()内。 但是,通过使用闭包,我们可以扩展这个作用域并从其作用域之外调用它。


Inner functions help us in defining factory functions. A factory function is a function that creates another object. For example:
内部函数帮助我们定义工厂函数(actory functions)。 工厂函数是创建另一个对象的函数。 例如:

def power_generator(num):

    # Create the inner function
    def power_n(power):
        return num ** power

    return power_n

power_two = power_generator(2)  
power_three = power_generator(3)  
print(power_two(8))  
print(power_three(4))  

Output
输出

256
81


In the script above, from the power_n(power) function, we have created two other objects, power_two and power_three. This makes power_n(power) a factory function since it generates the power_two and power_three functions for us using the parameter we pass it.
在上面的脚本中,从 pwoer_n(power) 函数中,我们创建了另外两个对象,power_two 和 power_three。 这使得 power_n(power) 成为一个工厂函数,因为它使用我们传递给它的参数为我们生成 power_two 和 power_three。


Conclusion
总结


An inner function is simply a function that is defined inside another function. The inner function is able to access the variables that have been defined within the scope of the outer function, but it cannot change them. There are a number of reasons as to why we may need to create an inner function. For instance, an inner function is protected from what happens outside it. Inner functions are also a good way of creating closures in Python.
内部函数只是在另一个函数内部定义的函数。 内部函数可以访问在外部函数范围内定义的变量,但不能更改它们。 我们需要创建一个内部函数的原因有很多。 例如,内部函数受到保护,不受外部发生的事情的影响。 内部函数也是在 Python 中创建闭包的好方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值