python中的变量作用域(对于来自perl的人)

Posted

技术标签:

【中文标题】python中的变量作用域(对于来自perl的人)【英文标题】:Variable scoping in python (for someone coming from perl) 【发布时间】:2021-10-11 21:46:54 【问题描述】:

我是 python 新手,出于必要,我选择了它 - 用于搅拌机 API。

作为一个来自 Perl 的人(以及更少的 javascript),我认为我遇到了 WRT 变量作用域的陷阱。例如在 Perl 中:

use strict;

my @list = ('a'..'z');

for my $v (@list)  print $v; 
print $v;

在 Python 中产生错误

mylist=['a', 'b', 'c']

for v in mylist:
    print(v)

print (v)

工作正常,最后一条语句打印'c'。

在 Javascript 中:

var list = ['a', 'b', 'c']

for (let j=0; j < list.length; j++)  console.log(j, list[j]) 
console.log(j);

会抛出一个错误(“j is not defined” - 除非我省略let,在这种情况下它的行为类似于 Python)

所以我知道for v in mylist i python 在外部范围内定义了一个变量 - 与 Perl(和部分 javascript)不同的行为。

虽然我发现大部分转换都相对简单,但变量作用域(及其表亲,将内置函数重新定义为变量的能力)令人困惑且难以捕捉(没有 use strict - 唉)。

因此问题是:在 Python 中变量作用域的主要区别是什么,当来自 Perl 时应该牢记这些区别?

我对范围界定特别感兴趣 - 一般过渡问题已得到很好的回答 here 并且常见的陷阱得到了很好的解决 here

【问题讨论】:

【参考方案1】:

在 The Python Language Reference 中提到过,专门用于循环的是Compound statements / The for statement。你会看到声明:

目标列表中的名称在循环结束时不会被删除,但如果序列为空,则它们根本不会被循环分配。

还可以在执行模型下查看名称绑定。

【讨论】:

【参考方案2】:

perl中看到的错误原因: 您使用了my 关键字,并且根据文档:Perl 中的my 关键字声明列出的变量对于定义它的封闭块是本地的。 my 的目的是定义静态范围。 所以在下面的代码中:

use strict;

my @list = ('a'..'z');

for my $v (@list) 
    print $v;

print $v;

变量$v 的范围在for 循环内,因此在循环外访问时会引发错误。 Javascript 中的 let 关键字也是如此。 要了解python 中的变量作用域,请参阅this,它有很好的解释。

【讨论】:

以上是关于python中的变量作用域(对于来自perl的人)的主要内容,如果未能解决你的问题,请参考以下文章

函数作用域小结

Python类中self的作用

Python变量作用域

在 Python 环境中管理 Perl 习惯

python闭包

老生常谈JavaScript闭包