首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定义其他函数内部的函数

定义其他函数内部的函数
EN

Stack Overflow用户
提问于 2016-10-25 05:34:55
回答 1查看 266关注 0票数 0

我在程序中的函数(Python)中定义了一个函数:

代码语言:javascript
复制
def func1:
   x = 5
   def func2(y):
      return x*y

x = 4
print func2(5)

这里的x的作用域是如何工作的,有和没有重新定义x=4的行?这是特定语言的行为吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-25 11:56:38

首先:你太懒了。在这里编写代码之前,至少要将其提供给有关语言的解释器或编译器,以排除明显的问题。在这种情况下,有两个:

  1. 由于语法错误,示例代码不会编译。通过在()的定义中添加func1来修正它。
  2. 您的示例代码将不会运行,因为func2在调用它的地方没有定义。

所以让我们试试

代码语言:javascript
复制
#!/usr/bin/env python

def func1():
   x = 5 
   def func2(y):
      #x = x + 1  # invalid: "x referenced before assignment"
      return x*y  # not invalid! reference to x is fine
   global func3
   func3 = func2

#print func3(5)  # undefined

func1()

print func3(5)
#print func2(5)  # undefined

有三行注释;它们在未注释时会产生错误。

如您所见,变量和函数的Python定义在默认情况下都是本地的:在函数中定义时,它们只适用于该函数,不能在其他地方使用。

函数外部定义的变量可以在函数内部使用。但是,它们只能读,不能写。这解释了为什么我们可以在func2中使用func2,但不能分配给它;当x = x + 1未注释时,它被解释为应用到func2中的另一个x变量,这就是为什么我们会收到一个错误抱怨它是未经初始化使用的。

此外,Python有https://en.wikipedia.org/wiki/Scope_(computer_science)#Global_scope变量,可以在程序中的任何地方使用;这些变量必须显式地标记为global

这与PHP非常相似(在PHP中变量也可以标记为global),并且与许多其他语言非常相似,比如C语言(C语言没有global,但有类似的extern)。

您正在尝试让一个函数(func2)使用在其定义的上下文中定义的变量(x),然后在定义x的上下文之外调用该函数,并让它仍然工作。能够做到这一点的函数称为闭包。

我们刚刚看到了Python只部分支持闭包。:函数可以读取这些变量,但不能修改它们。这已经比许多其他语言更好了。但是,完全闭包也可以修改这些变量。

例如,以下是有效的Perl代码:

代码语言:javascript
复制
#!/usr/bin/env perl

use strict;
use warnings;

my $func3 = sub { 1 };

my $func1 = sub
{
  my $x = 5;
  my $func2 = sub
  {
    my ($y) = @_;
    ++$x;
    $x*$y
  };
  $func3 = $func2
};

#&$func2(5);  # won't compile: func2 is undefined
print &$func3(5), "\n";  # prints 1
&$func1();
print &$func3(5), "\n";  # prints 30
print &$func3(5), "\n";  # prints 35

完全闭包支持传统上与动态范围相关联(即在运行时进行定义、可执行语句的计算)。这是因为它是由Lisp引入的,它是动态限定作用域的,而且在使用静态(词法)作用域的语言中很少支持它(在这些语言中,定义的范围是在编译时确定的,而不是在运行时确定的)。但是,这个Perl代码中的所有变量和函数定义都是静态范围的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40235074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档