Python内部函数集与非本地[重复]

Posted

技术标签:

【中文标题】Python内部函数集与非本地[重复]【英文标题】:Python inner function sets vs nonlocal [duplicate] 【发布时间】:2022-01-20 02:12:38 【问题描述】:

我相信我知道这个问题的答案,但我想仔细检查一下,因为我觉得这有点令人困惑。

def outerFunc():
    mySet = set()
    a = 0
    def innerFunc():
        mySet.add(1)
        mySet.add(2)
        a = 7
    innerFunc()
    print(mySet) # 1, 2
    print(a) # 0

这里,如果我想改变a的值,我需要使用nonlocal。集合改变的事实仅仅是因为集合是通过引用传递的吗?那么,在内部函数中,我们可以访问外部函数变量的值,但不能修改它们,除非它们是引用?

【问题讨论】:

sets 并没有什么特别之处。如果不使用nonlocal,您根本无法重新分配变量。如果您尝试使用mySet = 1, 2,那么不使用nonlocal 也将无法正常工作。 @GlennEdstrom 没有。可变性是无关的。相关细节是分配。 所以简而言之,分配总是自动本地。这意味着赋值语句(函数中的任何位置)会将该变量标记为本地变量(由编译器!)除非您使用nonlocalglobal。所涉及的对象的类型无关紧要,正如@rchome 所述,您可以使用mySet = 1, 2,您将获得与a = 7 相同的行为。但是,您可以引用来自封闭范围的变量,并且遵守正常的查找规则,而无需声明任何内容。 所以mySet.add(2) 有效,因为没有分配,它找到最接近的封闭范围并正确解析为您在outerFunc 中定义的集合。再说一次,被引用的对象的类型是无关紧要的。您可以在innerFunc 中执行print(a.as_integer_ratio()),它将正确解析为outerFunc 中的int 对象。当然,int 方法都不会改变int 的值——即int 对象是不可变的(它们缺少mutator 方法)。 Python的求值策略,既不是引用调用也不是值调用。该名称实际上是“通过共享调用”,尽管这是一个晦涩的术语。它是由 Barbara Liskov(Liskov Substitution Principle!)为语言 CLU 创造的,这对 OOP 的发展非常有影响。请注意,在 Java 社区中,他们说“Java 是按值调用,但值是对象引用”,这只是混淆了语义的实现,而且它不是纯面向对象的,因为 Java 有一个“原始”类型和“参考”类型之间的区别。 【参考方案1】:

可以查看pythondocument

在 Python 中,仅在函数内部引用的变量是 隐式全局。如果为变量赋值 函数的主体,除非明确说明,否则假定为局部函数 声明为全局。

所以如果你分配了一个变量并且没有global的变量只会影响本地。 例如,如果您将值分配给mySet,那么它也不会改变。

def outerFunc():
    mySet = set()   
    def innerFunc():
        mySet = 1
        mySet.add(2)
    innerFunc()
    print(mySet)  # ''

【讨论】:

以上是关于Python内部函数集与非本地[重复]的主要内容,如果未能解决你的问题,请参考以下文章

凸集与非凸集,凸函数与凹函数,凸优化

Python打破内部函数[重复]

3.1.9 类内部定义的函数:绑定方法与非绑定方法

Python入门-5函数:09嵌套函数(内部函数)-数据隐藏

变量如何在函数内部取值而不在任何地方声明它[重复]

Python:如何允许“内部函数”更改多个“外部函数”中的非局部变量