目录
1. 概述
- 从“变量作用域”这个词不难看出:变量有作用范围限制
2. 分类
- 按照作用域分类
- 全局(global):在函数外部定义
- 局部(local):在函数内部定义
3. 变量的作用范围
- 全局变量:在整个全局范围都有效
- 全局变量在局部可以使用(即,在函数内部可以使用在函数外部定义的变量)
- 局部变量:仅在特定的局部范围内有效
- 局部变量在出了自己的范围后就无法使用
- LEGB 原则
- L(Local)局部作用域
- E(Enclosing function locale)外部嵌套函数作用域
- G(Global module)函数定义所在模块作用域
- B(Builtin):python 内置模块的作用域
- LEGB 规定了查找一个名称的顺序为:local-->enclosing function locals-->global-->builtin
少废话,上例子
# 例1
num1 = 100 # 全局变量
def func():
print("num1 =", num1)
num2 = 99 # 局部变量
print("num2 =", num2)
return None
print("num1 =", num1)
func()
print("num2 =", num2)
- 运行结果
num1 = 100
num1 = 100
num2 = 99---------------------------------------------------------------------------
NameError……name 'num2' is not defined
4. 将局部变量提升为全局变量
- 使用 global
少废话,上例子
# 例2
def func():
global num1
num1 = 100
print("num1 =", num1)
num2 = 99
print("num2 =", num2)
return None
func()
print("num1 =", num1)
- 运行结果
num1 = 100
num2 = 99
num1 = 100
5. 内建函数 globals() 与 locals()
- 通过 globals() 和 locals() 可以显示出全局变量和局部变量
少废话,上例子
# 例3
num1 = 1
num2 = 2
def func(n1, n2):
n3 = 666
print("Local s= {0}".format(locals()))
print("Globals = {0}".format(globals()))
return None
func(11, 22)
- 运行结果
Locals = {'n1': 11, 'n2': 22, 'n3': 666}
Globals = {'name': 'main', 'doc': None, 'package': None, 'loader': <_frozen_importlib_external.SourceFileLoader object at 0x000001C21D86E940>, 'spec': None, 'annotations': {}, 'builtins': <module 'builtins' (built-in)>, 'file': '.\globals & locals.py', 'cached': None, 'num1': 1, 'num2': 2, 'func': <function func at 0x000001C21D82C2F0>}
6. 邪恶的 eval() 与 执行者 exec()
(1) eval()
- 把一个字符串当成一个表达式来执行, 返回表达式执行后的结果
- 示例
# 例4 eval(string_code, globals=None, locals=None)
num1 = 100
num2 = 200
num3 = num1 + num2
num4 = eval("num1+num2")
print(num3)
print(num4)
- 运行结果
300
300
(2) exec()
- 跟 eval() 功能类似, 但 exec() 不返回结果
- 示例
# 例5 exec(string_code, globals=None, locals=None)
num1 = 100
num2 = 200
num3 = num1 + num2
num4 = exec("print('num1 + num2 =', num1+num2)")
print(num3)
print(num4)
- 运行结果
num1 + num2 = 300
300
None
7. 递归函数
(1) 概述
- 简单地说,就是“我调用我自己”
- 优点:简洁,容易理解
- 缺点:对递归深度有限制,消耗资源大
- python 对递归深度有限制,超过限制报错
- 也可以手动更改递归深度
- 写递归程序时,要注意结束条件
(2) 少废话,上例子
# 例6 错误示范
num = 0
def func(): # 会暴走的
global num
num += 1
print(num)
func() # 调用自己
return None
func()
- 运行结果
先是像 excel 一样,纵向数字累加,然后抛出异常。
RecursionError……maximum recursion depth exceeded while calling a Python object
递归错误:调用 python 对象时超过了最大递归深度。
# 例7 斐波那契额数列
# 数学公式为: f(1) = 1, f(2) = 1, ... f(n) = f(n-1) + f(n-2)
def fib(n): # n 表示斐波那契数列的第 n 个数
if n == 1 or n ==2: # or 表示或者
return 1
return fib(n-1) + fib(n-2)
print(fib(10))
- 运行结果
55