一、上节回顾:
1、文件的修改操作、删除操作、with 语句
函数:函数的定义:def 函数名(形参1,形参2.。。。)
函数的调用:函数名(实参1,实参2)
函数的返回值:
定义阶段:return
三种情况:没有返回值,返回一个值,返回多个值
调用阶段:接收返回值,变量=函数名()
函数的参数:
形参:(定义阶段)
位置参数
默认参数(关键字参数)
实参:(调用阶段)
按照位置传参数
按照关键字传参数
二、作业讲解:
1、
# # 写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素, # # 并将其作为新列表返回给调用者
def func1(l): new_1=l[1::2] return new_1 # ret=func1([1,2,3,4,5]) # print(ret)
2、# 写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5
def func2(l): return len(l)>5 ret=func2([1,"dfdg",32,35,56,7,]) print(ret) #True
3、
# 写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,
# 并将新内容返回给调用者。
# 第一种方法: def func3(l): if len(l)>2: return l[:2] else:return l # 第二种方法 def func3(l):return l[:2]
4、
# 写函数,检查用户传入的对象(字符串、列表、元组)
# 的每一个元素是否含有空内容,并返回结果。
def func8(s_l_t): for i in s_l_t: if not i and i !=0 and i !=False: return True else: return False
5、
# 写函数,检查传入字典的每一个value的长度,如果大于2,
# 那么仅保留前两个长度的内容,并将新内容返回给调用者。
#PS:字典中的value只能是字符串或列表
# 第一种方法 def func6(dic): for k in dic: value=dic[k] if len(value)>2: dic[k]=value[:2] return dic # 第二种方法 def func7(dic): for k in dic: dic[k]=dic[k][:2] return dic
6、
# 写函数,接收两个数字参数,返回比较大的那个数字。
# 方法一 def func9(a,b): if a>b: return a else:return b print(func9(1,2)) # 方法二(三元运算符) c=a if a>b else b
三、今日内容
(一)参数
(1)位置参数
(2)默认参数
(3)动态参数
1、动态参数
def func(*args) #在参数面前加个*,这个参数就是动态参数了, print(args) 使用的时候,所有接收过来的参数都被组织成一个元组的形式
2、位置参数和动态参数相结合,动态参数必须写在位置参数的后面
def func(a,b,c,*args): print(a,b,c) print(args) ret=func(1,2,3,"sxfsd",{1213}) print() # 1 2 3 # ('sxfsd', {1213})
3、默认参数,
(1)只传前面三个的时候
def func(a,b,c,key="key",*args): print(a,b,c) print(key) print(args) ret=func(1,2,3,) print() #1 2 3 # key # ()
(2)传全部的时候
def func(a,b,c,key="key",*args): print(a,b,c) print(key) print(args) ret=func(1,2,3,"sxfsd",1,2,{1213}) print() # 1 2 3 # sxfsd # (1, 2, {1213})
4、关键字参数
按照顺序: 位置参数 - 动态参数 - 默认参数- 关键字参数
def func(a,*args,key="key",**kwargs): print("a:",a) print("args:",args) print("key:",key) print("kwargs:",kwargs) ret=func(1,2,3,"sxfsd",1,{1213},q="haohao",qq="dajia") # a: 1 # args: (2, 3, 'sxfsd', 1, {1213}) # key: key # kwargs: {'q': 'haohao', 'qq': 'dajia'}
5、例子:动态参数的例子 求和
def my_sum(*args): sum_2=0 for i in args: sum_2+=i return sum_2 ret=my_sum(1,2,33,44) print(ret) #80 ret1=my_sum(11,22,33) print(ret1) #66
6、魔性用法,打散列表
def my_sum(*args): #聚合 print(args) l=[1,2,234,546] ret2=my_sum(l) #([1, 2, 234, 546],) ret=my_sum(l[0],l[1],l[2],l[3]) #(1, 2, 234, 546) ret1=my_sum(*l) #(1, 2, 234, 546) 按顺序打散
7、只有作为实参和形参才可以加**
def func(**kwargs): print(kwargs) func(d=2,g=3) #{'d': 2, 'g': 3} dic={'a':1,"b":2} func(**dic) #{'a': 1, 'b': 2}
8、总结:
(1)动态参数: args :接收所有按照位置传的参数,接收到的是参数组成的元组
**kwargs :接收所有按照关键字传的参数,接收到的是参数组成的字典
(2) 所有的参数的顺序:位置参数,*args,默认参数,**kwargs
(3)魔性的用法:
在调用函数的时候可以打散: *l **dic
(二)命名空间
namespace 命名空间,名称空间
(1)局部命名空间:每一个函数都有自己的命名空间
(2)全局命名空间:写在函数外面的变量名
(3)内置命名空间:python解释器启动之后可以使用的名字
python 解释器运行起来的加载顺序:
先所有内置命名空间的中的名字————然后按照顺序加载全局命名空间中的名字
局部命名空间中的名字,在调用函数的时候产生,并且随着调用的结束而消失
1、函数的嵌套调用 从全局调用局部 (启动顺序)
def func2(): print("in func2 now") print("多些一行") if True: print("又多些一行") return "func2的返回值" def func(): ret=func2() print(ret) n=20 print(n) func() #in func2 now # 多些一行 # 又多些一行 # func2的返回值 # 20
2、函数的嵌套定义 在全局命名空间不能调用局部命名空间:
结果是无法调用
3、加载顺序造成的问题
def func(): print(1) def func(): print(2) func() # 2
def len(x): print("*****%s*****"%x) len("123") #*****123*****
4、作用域是指的一个名字可以使用的区域
局部作用域指向 全局作用域
n=0 def func1(): def func2(): print(n) func2() func1() #0
5、总结:
作用域:一个名字可以使用的区域
全局作用域:内置名字空间和全局名字空间中的名字都属于全局作用域
局部作用域:局部名字空间中的名字属于局部作用域
局部作用遇到:可以使用全局作用域中的变量
而全局作用域不能使用局部作用域中的变量
局部作用域还可以嵌套更小的局部作用域
作用域链:小范围作用域可以使用大范围的变量,但是作用域链是单向的,不能反向应用
6、func 的定义 以及调用
作用域链
n=0 def func1(): n=1 def func2(): n=2 def func3(): n=3 print(n) func3() func2() func1() # 3
7、globals() 保存了在全局作用域中的名字和值
locals() 中的内容会根据执行的位置来决定作用域中的内容
如果在全局中执行 两者的打印结果是一致的
def func(): a=10 b=20 print(locals()) #保存了当前作用域中的变量 print(globals()) n=10 m=22 print(globals()) #保存了在全局作用域中的名字和值 func()
8、函数的嵌套调用和函数的嵌套定义
命名空间:三种:内置 全局 局部
作用域:两张:全局 局部
作用域链:名字的使用 是从小到大范围的就近事件
9、 小范围可以使用大范围的,但是不能修改
如果想修改,可以使用global关键字 ——尽量避免使用
n=1 def func(): global n n+=1 func() print(n) #2
这个global 使用的是全局的变量 改变了最外面的n的值
10、nonlocal 就近原则(使用上一级变量n),不会改变全局的变量(两层使用)
n=5 def func(): n=1 def func2(): nonlocal n n+=1 func2() print(n) func() print(n) #2 #5
11、总结:
global 和locals方法
小范围可以使用大范围 但是不能修改
如果想修改全局的,使用global关键字----尽量避免
如果想修改最近拥有该变量的外层函数的:使用nonlocal----不影响全局
(三)函数的名字
1、函数可以赋值
# 函数的名字 def func(): print("in func") return 10 print(func) #<function func at 0x0000000002082EA0> f=func print(f) #<function func at 0x0000000002082EA0> t=func print(t) #<function func at 0x0000000002082EA0> print(t()) #in func #10 print(f()) #in func #10 print(func()) #in func #10
2、总结:
第一类对象的概念
函数名可以赋值
可以作为一个数据结构的元素
可以作为一个函数的参数
可以作为一个函数的返回值