在其他函数中定义函数 [英] Defining functions inside of other functions

查看:53
本文介绍了在其他函数中定义函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

def func1:x = 5def func2(y):返回 x*yx = 4打印 func2(5)

这里 x 的范围如何工作,没有重新定义 x=4 的行的 AND?这是特定于语言的行为吗?

解决方案

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

  1. 由于语法错误,您的示例代码无法编译.通过在 func1 的定义上添加 () 来修复它.
  2. 您的示例代码将无法运行,因为 func2 未在调用位置定义.

那就试试吧

#!/usr/bin/env pythondef func1():x = 5def func2(y):#x = x + 1 # 无效:x 在赋值前被引用"return x*y # 不是无效的!对 x 的引用很好全局函数3功能 3 = 功能 2#print func3(5) # 未定义函数 1()打印 func3(5)#print func2(5) # 未定义

注释了三行;取消注释时它们会产生错误.

如您所见,Python 对变量和函数的定义默认是局部:在函数中定义时,它们仅适用于该函数,不能在其他地方使用.>

在函数外部定义的变量可以在函数内部使用.但是,它们只能阅读,不能.这就解释了为什么我们可以在 func2 中使用 x 但不能赋值给它;当 x = x + 1 被取消注释时,它被解释为应用到 func2 中不同的 x 变量,这就是为什么我们会得到一个错误,抱怨它在未初始化的情况下使用.

此外,Python 还具有全球 变量,可以在程序中任何地方使用;此类变量必须显式标记为global.

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

您试图让函数 (func2) 使用在其定义上下文中定义的变量 (x),然后在上下文之外调用该函数,其中x 已定义并且仍然可以工作.可以做到这一点的函数称为闭包.

我们刚刚看到 Python 仅部分支持对于闭包:函数可以读取这样的变量,但不能修改它们.这已经比许多其他语言要好.但是,完整闭包也可以修改此类变量.

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

#!/usr/bin/env perl使用严格;使用警告;我的 $func3 = sub { 1 };我的 $func1 = sub{我的 $x = 5;我的 $func2 = sub{我的 ($y) = @_;++$x;$x*$y};$func3 = $func2};#&$func2(5);# 不会编译:func2 未定义打印 &$func3(5), "\n";# 打印 1&$func1();打印 &$func3(5), "\n";# 打印 30打印 &$func3(5), "\n";# 打印 35

全闭包支持传统上与动态范围(即制作定义可执行语句,在运行时评估).这是因为它是由动态作用域的 Lisp 引入的,并且在使用 静态(词法)范围(其中定义的范围在编译时确定,而不是在运行时确定).但是这个 Perl 代码中的所有变量和函数定义都是静态作用域的.

I defined a function inside of a function in a program (Python):

def func1:
   x = 5
   def func2(y):
      return x*y

x = 4
print func2(5)

How does the scope for x here work, with AND without the line that redefines x=4? Is this language-specific behavior?

解决方案

First of all: you're being too lazy. Before you write code here, at least feed it to an interpreter or compiler for the language in question to weed out the obvious problems. In this case, there are two:

  1. Your example code won't compile due to a syntax error. Fixing it by adding () on the definition of func1.
  2. Your example code won't run due to func2 being undefined where it is called.

So let's try

#!/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

Three lines are commented; they produce errors when uncommented.

As you can see, Python definitions, of both variables and functions, are local by default: when defined within a function, they only apply within that function, and cannot be used elsewhere.

Variables defined outside a function can be used inside the function. However, they can only be read, not written. This explains why we can use x inside func2 but cannot assign to it; when x = x + 1 is uncommented, it is interpreted as applying to a different x variable inside func2, which is why we'll get an error complaining that it is used uninitialized.

In addition, Python has global variables, which can be used anywhere in the program; such variables must be marked global explicitly.

This is very similar to PHP (in which variables can also be marked as global) and fairly similar to many other languages, such as C (which has no global, but the similar extern).

You're trying to have a function (func2) use a variable (x) defined in the context of its definition, then call the function outside the context where x is defined and still have it work. Functions that can do this are known as closures.

We've just seen that Python only has partial support for closures: the function can read such variables, but cannot modify them. This is already better than many other languages. However, a full closure can also modify such variables.

For instance, the following is valid Perl code:

#!/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

Full closure support is traditionally associated with dynamic scoping (i.e. making definitions executable statements, evaluated at run time). This is because it was introduced by Lisp, which was dynamically scoped, and support for it is rare in languages that use static (lexical) scoping (in which the scope of definitions is determined at compile time, not at run time). But all of the variables and function definitions in this Perl code are statically scoped.

这篇关于在其他函数中定义函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆