一:函数对象
函数是第一类对象,即表示函数可以当做数据传递
#可以被引用
把函数内存地址赋值给一个变量名,仍然遵循函数的调用规则 #可以被当做参数传递
传递的是函数的运行的结果 #可以当做返回值
把函数作为返回值返回的话,返回的结果是函数的内存地址 #可以当做容器类型的元素
意思就是可以作为列表和字典的元素
利用函数的特性,可以取代多分枝的if
def auth(): print("登陆......") def register(): print("注册.......") def seach(): print("查看........") dic = { "1":auth, "2":register, "3":seach, } def interactive(): while True: msg = """1 登陆 2 注册 3 查看""" print(msg) choice = input("请输入选择:").strip() if choice not in dic: print("没有该功能编号") continue else: dic[choice]() interactive()
二:函数的嵌套
2.1.函数的嵌套调用
在函数中调用了其他函数
def max2(x,y): if x > y: return x else: return y def max3(x,y,z): res1=max2(x,y) res2=max2(res1,z) return res2 print(max3(11,199,2))
2.2.函数的嵌套定义
在函数中定义其他函数
函数的嵌套定义只能在定义的同一级别调用
def func1(): print("weqwewq") def func2(): #在函数func1中定义func2 print("dsadas") print(func2) #打印函数地址 print(func2())#运行函数,打印函数的返回值 func2()#运行函数,print("dsadas") func1()
#嵌套函数调用
def f1():
print("f1")
def f2():
print("f2")
def f3():
print("f3")
def f4():
print("f4")
f4()
f3()
f2()
f1()
三:名称空间与作用域
3.1.什么是名称空间
名称空间有内置名称空间、全局名称空间、局部名称空间,名称空间存放着名字与值的绑定关系
内置名称空间存放python字自带的名字,内置的名字在解释器启动时生效,在解释器关闭后失效
全局名称空间存放文件级别的名字,要求是顶头写的:如全局变量、函数名等,全局的名字在文件执行的时候生效,在文件结束或文件执行期间被删除的时候失效
局部名称空间存放在函数内定义的名字(函数内的参数和函数内的名字),在函数调用时生效,在函数调用结束时候失效
3.2.名称空间的加载顺序
内置名称空间》》全局名称空间》》局部名称空间
在全局无法查看到局部的名称,但是在局部却可以查看全局的名称
四:作用域
3.1.作用域即范围
全局范围(内置名称空间与全局名称空间属于该范围):全局存活全局有效
局部范围:函数调用时存活,调用结束时失效,局部有效
3.2.作用域关系在函数定义阶段就已经固定,与函数的调用位置没有关系
def f1(): #定义函数f1 def f2():#嵌套定义函数f2
print(x) #打印变量x的值 return f2 #返回函数f2的内存地址 x=100 #定义全局变量 x = 100 def f3(func): #定义函数f3 x=2 #定义局部变量x=2,其作用域仅在函数f3内有效 func() #执行传给的函数 x=10000 #再次定义一个全局变量x=10000,该全局变量覆盖了上一个,x=100全局变量已经失效 f3(f1()) #执行,首先调用函数f1,定义函数f2,在定义阶段函数f2中x的作用域是全局范围,所以获取的是全局变量x的值,得到返
#回的函数f2的内存地址,把其内存地址当做实参传递给函数f3,调用函数f3,局部变量x=2无效,于是输出x的值10000
五:闭包函数
#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域 #应用领域:延迟计算 from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get baidu=index(‘http://www.baidu.com‘) print(baidu().decode(‘utf-8‘))
#内部函数包含对外部作用域而非全局作用域的引用 #提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,包起来喽,包起呦,包起来哇 def counter(): n=0 def incr(): nonlocal n x=n n+=1 return x return incr c=counter() print(c()) print(c()) print(c()) print(c.__closure__[0].cell_contents)