函数是第一类对象: 指的是函数名指向的值(函数)可以被当作数据去使用
可以被引用
可以当做参数传给另外一个函数
可以当做一个函数的返回值
可以当做容器类型的元素
函数的嵌套分为两大类:
一、函数的嵌套调用:在调用一个函数过程中,其内部代码又调用了其他函数
二、函数的嵌套定义:一个函数内部又定义了另外一个函数
名称空间namespace
名称空间就是用来存放名字与值的内存地址 绑定关系的地方(内存空间)
age=18
但凡查找值一定要通过名字,访问名字必须去查找名称空间
名称空间分为三大类:
内置名称空间:存放的是python解释器自带的名字
例如:len max print
全局名称空间:存放的是文件级别的名字
例如:以下名字中 xyz\foo都会存放于全局名称空间中
x=1
y=1
if x=1:
z=3
while True:
b=4
break
def foo():
m=3
局部名称空间:在函数内定义的名字
例如:
foo内的m这个名字一定是存放于一个局部名称空间中的
生命周期:
内置名称空间:在解释器启动时则失效,解释器关闭则失效
全局名称空间:在解释器执行python文件时则生效,文件执行完毕后则失效
局部名称空间:只在调用函数时临时产生该函数的局部名称空间,该函数调用完毕则失效
加载顺序:
内置->全局->局部
查找名字的顺序:
基于当前所在位置往上查找
假设当前站在局部,查找顺序:局部->全局->内置
假设当前站在全局,查找顺序:全局->内置
名字的查找顺序,在函数定义阶段就已经固定死了(即在检测语法时就已经确定了名字的查找顺序),与函数的调用位置无关,也就是说无论在任何地方调用函数,都必须回到当初定义函数的位置去确定名字的查找关系
作用域:
域指的是范围,作用域指的就是作用的范围,分为两种
全局作用域:包含的是内置名称空间与全局名称空间中的名字
特点:全局有效,全局存活
局部作用域:包含的是局部名称空间中的名字
特点:局部有效,临时存活
global :在局部声明一个名字来自于全局作用域的,可以用来在布局修改全局的不可变类型
x=1
def foo():
global x
x=2
foo()
print(x)
nonlocal:声明一个名字是来自于当前层外一层作用域的,可以用来在局部修改外层函数的不可变类型
x=0
def f1():
x=111
def f2():
nonlocal x
x=222
f2()
print(x)
f1()
print(x)
闭包函数
闭:指的是闭包函数是定义在一个函数内部的函数
包:指内部函数包含对外层函数作用域名字的引用
需要结合函数对象的概念将闭包函数返回到全局作用域去使用,从而打破函数的层级限制
def outter():
x=111
def inner():
print(x)
return inner
f=outter() #f=outter内的inner
def func():
x=3333
f()
func()
闭包函数提供了一种为函数体传值的解决方案
为函数体传值的方式一:参数
def func(x,y):
print(x+y)
func(1,2)
为函数体传值的方式二:闭包
def outter(x,y):
def func():
print(x+y)
return func
f=outter(1,2)
f()
f()
f()