【问题标题】:In Python, what is the operating principle to change from within a function an object outside of a function?在 Python 中,从函数内部更改函数外部对象的操作原理是什么?
【发布时间】:2021-02-09 19:26:59
【问题描述】:

在 Python 中,我发现以下与变量作用域相关的函数行为有些令人费解。似乎函数可以在函数之外更改数组的元素,但不能完全替换数组。这是什么工作原理?

a = np.array([2,3,5])
b = np.array([2,3,5])

def fun1():
    a[1] = 100
    return

def fun2():
    b = -1.1
    return

fun1()
print(a)

fun2()
print(b)

【问题讨论】:

  • 你能澄清你在问什么吗?您是在问分配范围的规则是什么?您是否在问为什么这些规则会导致这种行为?您是在问为什么这种行为被认为是可取的?
  • 这里缺少的关键是assignment 永远不会变异。简单赋值 b = -1.1 只是将局部变量 b 绑定到值 -1.1。另一方面,fun1 使用a[1] = 100,实际上只是对a.__setitem__(1, 100) 的调用,它是一个mutator 方法。一个很好的概述:nedbatchelder.com/text/names.html
  • "但不能完全替换阵列。"这没有任何意义。这不是 python 变量的工作方式。变量是指给定命名空间中的对象的名称。您可以更改名称所指的内容,但这不会“替换”对象。您可以将变量视为可以放置在对象上的名称标签,并且可以随意移动而不改变实际对象的任何内容
  • 这能回答你的问题吗? Why does writing to a variable change its scope?
  • 这能回答你的问题吗? Short description of the scoping rules?

标签: python scope


【解决方案1】:

Python 作用域按 LEGB 顺序排列,首先检查 Local、Enclosure、Global Scope 和 Bult-in 作用域 当您在数组元素中搜索时,python 会搜索现有变量并引用它,因为函数范围内没有变量,它会在范围内向上移动

def fun3():
    c[0] = 0
    return

fun3 会打印一个错误 C is not defined 不会使 c = [0], 它会尝试在每次搜索的范围内上升之后,首先在局部范围内(在这种情况下的函数内)找到变量 C

但是当您执行 b = 1.1 时,它会直接分配变量,它会优先考虑局部范围并在函数内简单地定义其值

def fun5():
     b = -1.1
     print(b) # prints local value, -1.1
     return
print(b) #prints original array)

同时

def fun6():
    b = [2,3,4]
    b[1] = 500
    print(b) #would print [2,500,4]
    return
print(b) #would print original array

现在在 fun6 中,因为新的 b 数组在范围内,b[1] 操作首先引用本地范围,并且它们只更改本地数组而不更改原始 b 数组,这是因为它更接近于b 在本地范围内。如果您注释第一行,下一个更接近的引用将是在文件开头声明的原始 b 因此更改将影响该范围的变量 b

用户 juanpa.arrivillaga 也先在回复中提到过

【讨论】:

  • “声明语法”不是标准术语。 Python 实际上并没有变量声明(除非你计算变量注释)
  • 是的,不是标准术语,是一种更简单的解释方式,而不是深入研究 python 解释器,mutate 语法也不是,但我认为上下文中的含义很明显,我可以改变但我什至不确定这是否是 OP 想要的主要答案@juanpa.arrivillaga
  • 好吧,我不认为在 Python 中不存在的其他语言中具有特定含义的“声明”可以简化任何事情,您不需要深入研究解释器。在许多语言中,您可以声明变量,也可以分配给变量。在 Python 中,只能赋值给变量
  • @juanpa.arrivillaga 是的,你是对的。我的意思是,在 python 上你只能分配或调用命名一个变量,是的,你不能简单地做一个 int b;并声明一个稍后要分配的变量,我在深入研究解释器的意思是查看哪些内部函数 x[0] = 调用与哪些函数 x = 在 python 解释器内部调用
猜你喜欢
  • 1970-01-01
  • 2018-03-10
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多