非本地与静态相同吗?

Posted

技术标签:

【中文标题】非本地与静态相同吗?【英文标题】:Is nonlocal same as static? 【发布时间】:2020-04-29 08:10:38 【问题描述】:

在python中,我们有一个关键字nonlocal。和 C++ 中的static 一样吗?如果我们在python中有嵌套函数,而不是在内部函数中使用nonlocal,我们不能只在外部函数中声明变量吗?这样它就真的是nonlocal了。

澄清:static 关键字如下在 C++ 中使用:


#include <iostream>
int foo () 
   static int sVar = 5;
   sVar++;
   return sVar;


using namespace std;
int main () 
   int iter = 0;
   do 
       cout << "Svar :" foo() << endl;
       iter++;
    while (iter < 3); 
 

在迭代中给出输出:

Svar :6
Svar :7
Svar :8

所以,Svar 保留了它的价值。

【问题讨论】:

一些代码将有助于澄清。 static 是一个关键字,其含义因上下文而异 好的,我会为static的上下文添加一些代码。 ...但是,这也可能是答案的一部分,但我觉得您在特定情况下指的是static 顺便说一句,它可以为比较不同语言的功能提供一些见解,但很少有两种不同语言的两个功能“相同”或等效。 【参考方案1】:

如果我们在python中有嵌套函数,而不是在内部函数中使用nonlocal,我们不能只在外部函数中声明变量吗?

没有。如果省略nonlocal,内部函数中的赋值将创建一个新的本地副本,忽略外部上下文中的声明。

def test1():
    x = "Foo"
    def test1_inner():
        x = "Bar"
    test1_inner()
    return x

def test2():
    x = "Foo"
    def test2_inner():
        nonlocal x
        x = "Bar"
    test2_inner()
    return x

print(test1())
print(test2())

...发出:

Foo
Bar

它和 C++ 中的 static 一样吗?

C++ static 变量实际上只是范围更窄的全局变量(即它们是跨函数调用存储的持久全局上下文)。

Python nonlocal 只是关于嵌套范围解析;外部函数的调用之间没有全局持久性(但会跨越来自同一外部函数调用的内部函数的多次调用)。

【讨论】:

【参考方案2】:

我对 C++ 中的static 的理解是它可以有多种含义。

我理解你所说的“C++ 中的static”是一个在调用之间保持状态的变量。 python 中最接近的是global 变量。

nonlocal 将嵌套函数中值的生命周期限制为封闭函数的生命周期。这是globallocal 之间的妥协。

如果您在内部函数中省略nonlocal,则那里的变量将具有与内部函数相同的范围和生命周期。除非,当然你是在读而不是写它,在这种情况下,它将匹配封闭函数的范围,但不能用于维护内部函数的任何状态。

【讨论】:

【参考方案3】:

“非本地”不是静态的。考虑下面的例子

def outer():
    x = "local"

    def inner():
        nonlocal x
        x = "nonlocal"
        print("inner:", x)

    inner()
    print("outer:", x)


def foo():
    foo.counter += 1
    print("Counter is", foo.counter)

outer()
foo.counter = 0

foo()
foo()
foo()

这段代码的输出是这样的 内部:非本地 外部:非本地 计数器为 1 计数器为 2 计数器为 3

变量foo.counter 相当于C++ 中的static 关键字。我希望这会有所帮助。

【讨论】:

以上是关于非本地与静态相同吗?的主要内容,如果未能解决你的问题,请参考以下文章

nginx配置中 root能指定非本地的文件路径吗

我可以将本地静态 html 页面重定向到在线资源吗?

Colab TPU 上的 RNN 运行速度与本地 CPU 版本相同

单例模式与静态方法的区别

gsutil rsync 在 gzip/非 gzip 本地/云位置之间同步

Python 函数在 AWS Glue 中返回非类型,即使是在本地机器上工作的相同函数