01 内容回顾
- 函数的参数:
- 实参角度:位置参数,关键字参数,混合参数。
- 形参角度:位置参数,默认参数,仅限关键字参数,万能参数
- 形参角度参数顺序:位置参数,*args,默认参数,仅限关键字参数,**kwargs
- *的魔性用法:
- 函数的定义时:代表聚合。
- 函数的调用时:代表打散。
- Python中存在三个空间:
- 内置名称空间:存储内置函数:print,input......
- 全局名称空间:py文件,存放的是py文件(除去函数、类内部的)的变量,函数名与函数的内存地址的关系
- 局部名称空间:存放函数内部的变量与值的对应关系。
- 加载顺序:内置名称空间,全局名称空间,局部名称空间(执行函数时)
- 取值顺序:就近原则,LEGB。
- 局部作用域只能引用全局变量,不能修改。
- 作用域:
- 全局作用域:内置名称空间+全局名称空间
- 局部作用域:局部名称空间
- 函数的嵌套
- globals() locals()
02 补充,global,nonlocal
-
默认参数的陷阱:
# 陷阱只针对默认参数是可变数据类型: def func(name,alist=[]): alist.append(name) return alist ret1 = func('hhh') print(ret1,id(ret1)) # ['hhh'] ret2 = func('kkk') print(ret2,id(ret2)) # ['hhh', 'kkk'] # 如果你的默认参数只想的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。
def func(a,list=[]): list.append(a) return list print(func(10,)) # [10] print(func(20,[])) # [20] print(func(100,)) # [10,100]
def func(a,list=[]): list.append(a) return list ret1 = func(10,) ret2 = func(20,[]) ret3 = func(100,) print(ret1) # [10, 100] print(ret2) # [20] print(ret3) # [10, 100]
-
局部作用域的坑
# 局部作用域的坑 # count = 1 # def func(): # count += 1 # print(count) # func() # # 报错 局部作用域中对全局变量进行了修改 # 在函数中,如果你定义了一个变量,但是在定义这个变量之前对其进行引用了,那么解释器认为:语法错误 # 应该在使用前先定义 # count = 1 # def func(): # print(count) # count = 3 # func() # # 报错 赋值前引用局部变量
-
global,nonlocal
-
global
-
# 1.在局部作用域声明一个全局变量 # name = 'hhh' # # def func(): # name = 'kkk' # print(name) # func() # kkk # print(name) # hhh def func(): global name name = 'kkk' print(name) # print(name) # 报错 func() # kkk print(name) # kkk
-
# 2.修改一个全局变量 count = 1 def func(): global count count += 1 print(count) # 1 func() print(count) # 2
-
-
nonlocal
# 1.不能操作全局变量 # 2.局部作用域:内层函数对外层函数的局部变量进行修改 def wrapper(): count = 1 def inner(): nonlocal count count += 1 print(count) # 1 inner() print(count) # 2 wrapper()4.
-
03 函数名的应用
-
# func() # 1.函数名指向的是函数的内存地址 # 函数名+()就可以执行此函数 # print(func,type(func)) # <function func at 0x013007C8> <class 'function'>
-
# 2.函数名就是变量。 # def func(): # print(666) # f = func # f1 = f # f2 = f1 # f2() # f() # f1() # func() def func(): print('in func') def func1(): print('in func1') func1 = func func1() # in func
-
# 3.函数名可以作为容器类数据类型的元素 def func1(): print('in func1') def func2(): print('in func2') def func3(): print('in func3') l1 = [func1,func2,func3] for i in l1: i() # in func1 # in func2 # in func3
-
# 4.函数名可以作为函数的参数 def func(): print('in func') def func1(x): x() print('in func1') func1(func) # in func # in func1
-
# 5.函数名可以作为函数的返回值 def func(): print('in func') def func1(x): print('in func1') return x ret = func1(func) ret() # in func1 # in func
04 格式化输出
# %s format
# name = 'zs'
# age = 18
# msg1 = '我叫%s,今年%s'%(name,age)
# msg2 = '我叫{},今年{}'.format(name,age)
# 新特性:格式化输出
# name = 'zs'
# age = 18
# msg = f'我叫{name},今年{age}'
# print(msg)
# 可以加表达式
# dic = {'name':'zs','age':18}
# msg = f'我叫{dic["name"]},今年{dic["age"]}'
# print(msg)
# count = 7
# print(f'最终结果:{count**2}') # 49
# name = 'zskkk'
# msg = f'我的名字是{name.upper()}'
# print(msg) # 我的名字是ZSKKK
# 结合函数写
# def _sum(a,b):
# return a + b
# msg = f'最终结果是:{_sum(10,20)}'
# print(msg) # 最终结果是:30
# 优点:
# 1.结构更简化。
# 2.可以结合表达式,函数进行使用。
# 3.效率提升很多。
05 迭代器
-
可迭代对象
-
字面意思:Python中一切皆对象。一个实实在在存在的值,叫对象
-
可迭代:更新迭代。重复的,循环的一个过程,更新迭代每次都有新的内容
-
可以进行循环更新的一个实实在在的值
-
专业角度:
-
内部含有
'_iter_'
方法的对象,可迭代对象。
-
目前学过的可迭代对象:str list tuple dict set range 文件句柄
-
-
获取对象的所有方法并以字符串的形式表现:dir()
-
判断一个对象是不是可迭代对象
# 获取一个对象的所有方法 dir() # s1 = 'asdfjkl' # l1 = [1,2,3] # print(dir(s1)) # print(dir(l1)) # print('__iter__'in dir(s1)) # True print('__iter__'in dir(range(10))) # True
-
小结
-
字面意思:可以进行循环更新的一个实实在在的值
-
专业角度:内部含有
'_iter_'
方法的对象,可迭代对象
-
判断一个对象是不是可迭代对象:
'_iter_'
in dir(对象)
-
str list tuple dict set range
-
优点:
- 存储的数据直接能显示,比较直观。
- 拥有的方法比较多。
-
缺点:
- 占用内存。
- 不能直接通过for循环,不能直接取值(索引,key除外)
-