{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## 变量的作用域\n", "\n", "变量的作用域(scope)决定了变量可以被访问和使用的代码区域。\n", "\n", "在Python中,变量的作用域主要有以下几种类型:\n", " - 局部作用域 (Local Scope):函数内部定义的变量, 仅在函数内部可见可用。\n", " - 嵌套作用域 (Enclosing Scope):在嵌套函数中,外部函数的变量对内部函数可见。\n", " - 全局作用域 (Global Scope): 在所有函数外部定义的变量,可以在整个程序中被访问。\n", " - 内置作用域 (Built-in Scope): 包含Python内置函数、变量和异常等。最外层作用域。 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 局部变量和全局变量\n", " - 赋值运算默认创建局部变量" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n", "10\n" ] } ], "source": [ "x = 10 # 全局变量\n", "\n", "def ff():\n", " y = 5 # 赋值运算默认创建局部变量\n", " print(x) # 可以访问全局变量 x\n", "\n", "ff() # 调用函数,输出10\n", "print(x) # 输出全局变量x的值,仍然是10\n", "# print(y) # 出错,y 在 ff 内部定义,是局部变量,在函数外部无法访问" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "''' 特别注意:下面代码发生错误。\n", "因为执行到 x = x + 2 ,首先将 x 登记为局部变量,\n", "接着计算右边的x + 2时,x还未被定义,所以会报错。\n", "'''\n", "x = 10\n", "\n", "def ff(): \n", " x = x + 2 # x += 2 等价\n", " \n", "ff()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 函数嵌套\n", "\n", "Python 变量访问优先级规则(LEGB),这也是变量的遮蔽顺序:Local(局部作用域) -> Enclosing(嵌套作用域) -> Global(全局作用域) -> Built-in(内置作用域)\n" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "5\n", "10\n" ] } ], "source": [ "x = 10 # 全局变量\n", "\n", "def outer():\n", " x = 5 # outer函数的局部变量\n", "\n", " def inner():\n", " x = 2 # inner函数的局部变量\n", " print(x) # 输出局部变量x的值\n", "\n", " inner() # 输出2\n", " print(x) # 输出outer函数的局部变量x的值,即 5\n", "\n", "outer() # 调用outer函数\n", "print(x) # 输出全局变量x的值,即10" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 如果打算给非局部变量赋值,需要特别申明" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### global 关键字功能\n", "\n", "想在函数内部修改全局变量,使用global关键字。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n" ] } ], "source": [ "x = 10 # 全局变量\n", "\n", "def func():\n", " global x # 声明使用全局变量 x\n", " x = 5 # 修改全局变量 x 的值\n", "\n", "func() # 调用函数,修改全局变量x的值\n", "print(x) # 输出全局变量x的新值,现在是 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### nonlocal 关键字功能\n", "\n", "函数嵌套时,如果想修改外层函数的局部变量,需要使用nonlocal关键字。" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n" ] } ], "source": [ "def outer():\n", " x = 5 # outer函数的局部变量\n", "\n", " def inner():\n", " nonlocal x # 声明x是outer函数的局部变量,而不是全局变量\n", " x = 10 # 修改outer函数的局部变量x的值\n", "\n", " inner() # 调用inner函数\n", " print(x) # 输出修改后的x值,即10\n", "\n", "outer() # 调用outer函数" ] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" } }, "nbformat": 4, "nbformat_minor": 4 }