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
。集合改变的事实仅仅是因为集合是通过引用传递的吗?那么,在内部函数中,我们可以访问外部函数变量的值,但不能修改它们,除非它们是引用?
【问题讨论】:
set
s 并没有什么特别之处。如果不使用nonlocal
,您根本无法重新分配变量。如果您尝试使用mySet = 1, 2
,那么不使用nonlocal
也将无法正常工作。
@GlennEdstrom 没有。可变性是无关的。相关细节是分配。
所以简而言之,分配总是自动本地。这意味着赋值语句(函数中的任何位置)会将该变量标记为本地变量(由编译器!)除非您使用nonlocal
或global
。所涉及的对象的类型无关紧要,正如@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内部函数集与非本地[重复]的主要内容,如果未能解决你的问题,请参考以下文章