Day19_名称空间和作用域_函数的嵌套_函数第一类对象的使用_闭包函数
一. 上节课复习
-
为何要使用函数
- 解决代码重用问题
- 统一维护
- 程序的组织结构清晰,可读性强
-
定义函数
- !!!先定义后使用
def funcname(arg1,arg2,....) #funcname = 函数体 '''描述信息''' 函数体 return value
- 定义无参函数
定义有参函数
定义空函数
-
调用函数
- 语句形式:foo()
- 表达式形式:foo(1,2)
- 函数调用作为另外一个函数的参数:print(foo(1,2))
-
函数返回值
- 不写return--->None
- return 一个值--->这个值
- return 多个值--->由这多个值组成的元组
-
函数的参数
- 形参
- 实参数
- 从实参的角度:
- 按位置传值 foo(1,2)
- 按关键字传值 foo(y=1,x=2)
- 混合传值 foo(1,y=2)
- 从形参角度:
- 位置参数 def foo(x,y,z)
- 默认参数 def foo(x,y=1)
- 什么时候用:
- 在调用函数时,每次调用传入的值都在变化,使用位置参数,变化较小使用默认参数
- 二者的位置排列:
- 位置参数必须在默认参数的左边
- 二者的特性:
- 位置参数 必须传值,默认参数可传可不传
- *args:
def foo (x,\*args) foo(1,2,3,4,5)
** kwargs:
def foo (x,**kwargs) foo(1,y=2,z=3)
二. 名称空间和作用域
- 名称空间
- 内置名称空间
- 全局名称空间
- 局部名称空间
- 作用域
- 全局作用域
- 局部作用域
- 名称空间的查询
- globals:查询全局名称空间的名字
- locals:查询局部名称空间的名字
三. 函数的嵌套及静态作用域
- 嵌套调用
- 嵌套定义 !!!函数嵌套时的执行顺序
def f1():
x = 1
print('----->f1 ',x)
def f2():
x = 2
print('---->f2 ',x)
def f3():
x = 3
print('--->f3 ',x)
f3()
f2()
f1() >>>----->f1 1;---->f2 2;--->f3 3
四.函数是第一类对象的概念
- 函数可以被赋值
def foo(): print('foo') print(foo) f = foo print(f)
- 把函数当成参数传递
def foo(): print('foo') def bar(func): >>><function foo at 0x00000000003E3F28>;foo print(func) func() bar(foo)
- 把函数当成返回值
def foo(): print('foo') def bar(func): print(func) return func f = bar(foo) print(f)
- 把函数当成容器类型的元素去用
def add(): print('==========function add') def delete(): print('==========function delete') def search(): print('==========function search') def change(): print('==========function change') def tell_msg(): msg = ''' delete:删除 add:添加 search:查询 change:更改 ''' print(msg) cmd_list = { 'add':add, 'delete':delete, 'search':search, 'change':change } while True: tell_msg() choice = input('please input your choice: ').strip() cmd_list[choice]()
五.闭包
-
闭包函数概念:
- 首先是内部定义的函数,该函数对外部作用域而不是全局作用域名字的引用
x =1 def f1(): x = 1000 def f2(): print(x) return f2 f = f1() f() print(f.__closure__[0]) print(f.__closure__[0].cell_contents) >>><1000 >>><cell at 0x0000000002177498: int object at 0x0000000001DC9EF0> >>>1000
from urllib.request import urlopen def f1(url): def f2(): print(urlopen(url).read()) return f2 baidu = f1('http://www.baidu.com') #爬网页 baidu()