值传递
在 Python 中,参数传递的机制是“共享传参”(Call by Object Reference 或 Call by Sharing)。这意味着函数参数接收的是对象的引用,而不是对象的副本。
具体含义
- 对于可变对象(如 list, dict, set 等):在函数中对对象的内容进行修改会影响到原对象。
- 对于不可变对象(如 int, float, str, tuple 等):在函数中对对象重新赋值不会影响到原对象,因为重新赋值会创建一个新的对象。
共享引用:函数参数传递的是对象的引用,而不是对象本身的副本。
- 如果是 可变对象,且只修改内容,不重新赋值,则会影响外部变量。
- 如果是 不可变对象,或者对可变对象重新赋值,则不会影响外部变量。
这种机制让 Python 的参数传递既有“值传递”的特点(对于不可变对象)又有“引用传递”的特点(对于可变对象),因此被称为“共享传参”。
作用域
Python 中的作用域问题总结
Python 中变量的作用域决定了变量在哪些范围可以被访问和修改。作用域规则遵循 LEGB 原则,并结合作用域的动态特点,形成了以下几点关键概念。
LEGB 原则
Python 变量的查找顺序分为四个作用域,从内到外依次是:
- Local(局部作用域):
函数或代码块内部定义的变量,优先级最高,只在函数或代码块内部有效。
- Enclosing(嵌套作用域):
嵌套函数的外层函数中定义的变量,对内层函数有效,但仅限于外层函数及其内部嵌套函数。
- Global(全局作用域):
脚本中定义的变量,在整个模块中有效。
在函数内若要修改全局变量,需使用 global 声明。
1 | x = "global variable" |
- Built-in(内置作用域):
Python 自带的内置模块、函数和变量,比如 print, len, int 等。
1 | print(len([1, 2, 3])) # 调用内置的 len 函数 |
常用关键字
global 关键字
- 用于在函数内声明全局变量。
- 使局部作用域中对变量的修改直接作用于全局作用域。
1 | x = 10 |
nonlocal 关键字
- 用于在嵌套函数中声明修改外层函数的局部变量。
- 作用域介于 local 和 global 之间。
1 | def outer(): |
嵌套函数的变量访问
- 嵌套函数可以访问外层函数的局部变量(闭包特性)。
- 如果需要修改外层变量,需要使用 nonlocal。
1 | def outer(): |
可变对象与作用域
对于可变对象(如列表、字典),函数内部的操作会直接影响外部对象的内容,但不会改变引用关系。
1 | x = [1, 2, 3] |
如果改变了对象的引用关系,则会生成新的局部变量,不影响全局对象:
1 | x = [1, 2, 3] |