函数进阶二
-
关键字
globla:在局部作用域声明全局变量(此变量只存在于全局,局部是没有的,但可以在局部进行更改)
- 声明一个全局变量
- 在局部要对全局变量进行修改时要用到global
def func(): global a a = 3 func() print(a)
nonlocal:在局部作用域对父级作用域变量进行修改时需要用到nonlocal
- 不能改变全局变量
- 在局部作用域中,对父级作用域的变量进行引用和修改,并且引用的哪层从那层以下此变量全部发生改变
def add_b(): b = 42 def do_global(): b = 10 print(b) def dd_nonlocal(): nonlocal b b = b + 20 #改变的是dd_nonlocal()和do_global()中b的大小 print(b) dd_nonlocal() print(b) do_global() print(b) add_b() 结果: 10 30 30 42
-
默认参数的坑
当你的默认参数如果是可变的数据类型,每次执行函数都是对同一个对象进行更改
def func(a,l=[]): l.append(a) return l print(func(1)) # [1,] print(func(2)) # [2,] print(func(3)) # [3,] 结果: [1,2,3]
-
函数名的应用
函数名是一个特殊的变量
-
函数名指向的是函数的内存地址,加上()就执行这个函数
-
函数名是一个变量
age1 = 12 age2 = age1 age3 = age2 print(age3) def func(): print(666) f1 = func f2 = f1 f2() f1() 结果: 12 666 666
-
函数名可以作为容器类类型的元素
def func1(): print('in func1') def func2(): print('in func2') def func3(): print('in func3') l = [func1,func2,func3] for i in l: i() 结果: in func1 in func2 in func3
-
函数名可以作为函数的实参
def func1(): print('in func1') def func2(argv): argv() print('in func2') func2(func1) 结果: in func1 in func2
-
函数名可以作为函数返回值
b = 666 def func1(argv): print('in func1') return argv ret = func1(b) print(ret) 结果: in func1 666
-
-
新的格式化输出 f'{}'
- f/F 不区分大小写
- {}中可加入表达式
- 可以结合函数
- 不能放一些特殊的字符 ! , : {} ;
-
可迭代对象
-
定义
可以重复迭代的实实在在的东西。
内部含有
'__iter__'
方法的对象目前接触到的有:str,dict,tuple,set,range,文件句柄
-
判断一个对象是否是可迭代对象
内置函数:dir()
print('iter' in dir(str))
-
优点:
- 直观。
- 操作方法比较多
-
缺点:
- 占内存
- 不能迭代取值(除去索引和字典的key)
-
-
迭代器
-
定义
字面意思:可以重复迭代的工具
专业角度:内部含有
'__iter__'
并且含有'__next__'
方法的对象,就是迭代器 -
可迭代对象转化为迭代器
- 使用内置函数iter()将可迭代对象转化为迭代器,使用next()对迭代器进行取值
# 迭代器可以迭代取值。利用next()进行取值 l1 = [1, 2, 3, 4, 5] # 内置函数iter() obj = iter(l1) # print(obj) print(next(obj)) print(next(obj)) print(next(obj)) print(next(obj)) print(next(obj)) print(next(obj)) 结果: 1 2 3 4 5 报错:StopIteration
-
python中的异常处理
try except
li = [1] try: li[100] except: IndexError
-
使用while循环模拟for循环循环机制
- 先要将可迭代对象转化成迭代器。
- 利用next对迭代器进行取值。
- 利用异常处理try一下防止报错。
li = [1,2,3,4,5] obj = iter(li) while 1: try: print(next(obj)) except StopIteration: break 结果: 1 2 3 4 5
-
优点:
- 非常节省内存
- 惰性机制
-
缺点:
- 不直观
- 操作不灵活
- 效率相对低
-
特性
l1 = [22, 33, 44, 55, 66, 77] obj = iter(l1) for i in range(3): print(next(obj)) for i in range(2): print(next(obj)) 结果: 22 33 44 55 66
-
可迭代对象与迭代器对比
-
可迭代对象
是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。
应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
-
迭代器
是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)。
-
-