一. 命名空间
1. 三种命名空间的区别
1. 内置命名空间
Python解释器一启动就可以使用的名字(print, input, str, list...)存储在内置命名空间中, 内置的名字在启动解释器的时候被加载进内存里.
2. 全局命名空间
在程序从上到下被执行的过程中, 依次被加载进内存的, 放置了我们设置的所有变量名和函数名.
3. 局部命名空间
函数内部定义的变量名或函数名, 当调用函数的时候, 才会产生这个命名空间, 随着函数执行的结束, 这个命名空间就又消失了.
2. 命名空间的依赖关系(依赖倒置, 上层模块依赖底层模块)
1. 在局部命名空间: 可以使用全局和内置命名空间的名字.
2. 在全局命名空间: 可以使用内置命名空间中的名字, 但是不能使用命名空间中的名字.
3. 在内置命名空间: 全局和内置命名空间中的名字都不能使用.
3. 函数调用的本质
1. 当在全局定义了内置命名空间中已经存在的名字时, 调用时会使用全局的名字(这种方法要杜绝!!!).
2. 当在局部定义了全局命苦空间中已经存在的名字时, 调用时用局部的名字.
def input(): print("我是全局的input") input() 输出: 我是全局的input
函数的调用: 函数名() <==> 函数的内存地址()
4. 函数名指向函数的内存地址, 非常重要!!!
def abc(): print('我是abc函数') def func(): print(abc) func()
输出: <function abc at 0x00000166F0D08F28>
二. 作用域
作用域就是作用范围, 按照生效范围可以分为全局作用域和局部作用域.
1. 全局作用域, 包含内置名称空间和全局名称空间, 在整个文件的任意位置都能被使用, 全局有效, 可以使用globals()和locals()查看.
a = 1 def func(): print(a) 输出: 1
2. 局部作用域, 只在局部范围有效, 可以使用locals()查看
def func(): a = 1 print(a) 输出: 错误!!!
3. 对于不可变数据类型, 在局部可以查看全局作用域中的变量, 但是不能直接修改, 如果要修改, 需要在程序的一开始添加global声明.
a = 1 def func(): global a a += 1
print(a) 输出: 1 func() print(a) 输出: 2
三. 函数的嵌套
1. 函数的嵌套定义:
def outer(): def inner(): print('inner') inner() outer()
输出: inner
2. 内部函数可以使用外部函数的变量, 要注意执行顺序
def outer(): a = 1 def inner1(): b = 2 print('inner1') def inner2(): print(a, b) print('inner2') inner2() inner1() outer()
输出:
inner1
1 2
inner2
3. 全局变量的修改global, nonlocal(声明了一个上层局部变量, 只找最近的上一层)
a = 1 def outer(): a = 2 print("我是outer的局部变量a=", a) def inner(): global a a += 10 print("我是inner的global a=", a) inner() print("我是最开始的全局变量a=", a) outer() print("我是后来的全局变量a=", a)
输出:
我是最开始的全局变量a= 1
我是outer的局部变量a= 2
我是inner的global a= 11
我是后来的全局变量a= 11
4. 局部变量修改之nonlocal
# 比较三个数, 并且将最大值输出
def max(a, b): return a if a>b else b def the_max(x, y, z) c = max(x, y) return max(c, z) print(the_max(1, 2, 3))
输出: 3