函数有可见范围,这就是作用域的概念。
内部函数不能在外边直接使用,会抛出Nameerror异常。因为它不可见。
作用域
- 一个标识符的可见范围,这就是标识符的作用域。一般来说就是变量的作用域
- 从嵌套解构例子看出
- 外层变量作用域在内层作用域可见
- 内层作用域中,如果定义了一个变量名o,相当于当前作用域中重新定义了一个新的变量名o。但是这个o并没有覆盖外层作用域中的变量名o。
全局作用域
- 在整个程序运行环境中都可见
局部作用域
- 在函数、类等内部可见
- 局部变量使用返回不能超过其所在的局部作用域
x = 5
def foo():
x+=1
foo()
- x+= 1 其实是x = x+1
- 相当于在foo内部定义一个局部变量x,你们foo内部所有x都是这个局部变量x
- 但是这个x还没有完成赋值,就被右边拿来做加1 操作了
全局变量global
x = 5
def foo():
global x
x += 1
print(X)
foo()
- 使用global关键字的变量,将foo内的x声明为外部的全局作用域中定义的x
- 全局作用域中必须有x的定义
闭包
自由变量:未在本地作用域中定义的变量,例如定义在内存函数外的
外层函数的作用域中的变量
闭包:就是一个概念,出现在嵌套函数中,指的是内层函数引用到了外层函数的自由变量。就形成了闭包。
def foo():
c = [0]
def ine():
c[0] += 1 #在函数ine中的使用方式为c的元素修改值,而不是重新定义变量
return c[0]
return ine #ine是一个函数对象
f = foo() #f是一个函数对象
print(f())#调用函数foo
- c在函数foo函数中定义过来,而且Ine中的使用方式是为c的元素修改值。而不是重新定义变量。
nonlocal关键字
使用nonlocal关键字,将变量标记为不在本地作用域定义,而在上级的某一级局部作用域中定义,但不能是全局作用域中定义。
def counter():
count = 0
def inc():
nonlocal count
count += 1
return count
return inc
foo = counter()
print(foo())
- count是外层函数的局部变量,被内部函数引用
- 内部函数使用nonlocal关键字声明count变量在上级作用域而非在本地作用域定义