我在程序中的函数(Python)中定义了一个函数:
def func1:
x = 5
def func2(y):
return x*y
x = 4
print func2(5)这里的x的作用域是如何工作的,有和没有重新定义x=4的行?这是特定语言的行为吗?
发布于 2016-10-25 11:56:38
首先:你太懒了。在这里编写代码之前,至少要将其提供给有关语言的解释器或编译器,以排除明显的问题。在这种情况下,有两个:
()的定义中添加func1来修正它。func2在调用它的地方没有定义。所以让我们试试
#!/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代码:
#!/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代码中的所有变量和函数定义都是静态范围的。
https://stackoverflow.com/questions/40235074
复制相似问题