函数、参数
#为解决可读性差,重复代码 #定义格式 """ def 函数名(形参): 函数体 return 返回值/结束函数,多个值以元组形式返回 #执行 函数名(实参)#需要和函数形参数量一致 """ #1、示例 def my_len(OBJ): count = 0 for i in OBJ: count += 1 return count a = [1, 2, 3] print(my_len(a)) #2、关键字参数 直接给形参赋值, 但位置传参一定在最后 def Test1(a, b, c): print(a, b, c) return a, b #Test1(1, 2, b = 3) #报错,不能给中间形参关键字传参 Test1(1, c = 2, b = 3) #可以,最后的关键字参数顺序可变 #3、默认参数 def Test2(a, b, c = 110): #1、默认参数必须放在形参最后;2、不传取默认,传值覆盖默认值 print(a, b, c) Test2(1, 2) #1 2 110 Test2(1, 2, 3) #1 2 3 #!!!函数的默认参数是可变数据类型时,无论使用多少次默认参数,都是同一个(共用) def L(a, list = []): list.append(a) return list list1 = L(10)#没传使用默认参数 list2 = L(123, [])#传空列表后,默认参数被覆盖 list3 = L('a')#没传仍然使用默认参数,当前默认参数为[10] print(list1, list2, list3)#[10, 'a'] [123] [10, 'a'] #4、动态参数,数量不确定或方便扩展,用 *args **kwargs(args和kwargs是约定俗成的写法,不是必须用这两个变量名) def Test3(*args, **kwargs): print("args", args)#(1, 2, 3)#接收位置参数,元组类型 print("kwargs", kwargs)#{'x': 4, 'y': 5}#接收关键字参数,字典类型 Test3(1, 2, 3, x=4, y=5) #!!!动态参数*args接收位置参数时,必须放在其他参数位置后,关键字参数之前; """!!!同理,**kwargs 也必须放在其他关键字参数之后,所以传参顺序是 (位置参数, *args, 关键字参数, **kwargs)""" # def Test4(a, b, c='test',*args): def Test4(a, b, *args, c='test'): print(a, b, args, c) Test4(1, 2, 4, c='Test')#1 2 (4,) Test #例 def Test5(*args): sum = 0 for i in args: sum += i return sum print(Test5(1, 2, 3, 5, 8))#19
#在函数的定义中, * 是聚合对象,所以如上 *args 接收多个参数 #在函数执行时, * 是打散可迭代对象,如下: def Test6(*args, **kwargs): #接收位置参数,元组类型 print("args", args)#args (1, 2, 3, 4, 5, 'x') print("*args", *args)#*args 1 2 3 4 5 x #接收关键字参数,字典类型 print("kwargs", kwargs)#kwargs {'y': 5, 'z': 6} # print("**kwargs", **kwargs)#报错,print()函数不支持关键字参数 a = [1, 2, 3] b = [4, 5] c = {'x': 4} d = {'y': 5} e = {'z': 6} Test6(*a, *b, *c, **d, **e)#这里实参的* 和 **为了标识传给不同类型的形参
#1、函数名 #打印 def Test1(): print('test1') print(Test1)#<function Test1 at 0x7feb2ddd4040> 函数名、地址 #赋值 T1 = Test1 T1() #做函数的参数 def Test2(a): a() print('test2') Test2(Test1) #做容器类的元素 def Test3(): print('test3') def Test4(): print('test4') L1 = [Test3, Test4] for i in L1: i() #做函数返回值 def Test5(a): print('test5') return a msg = Test5(Test4) print(msg)#Test4函数对象 msg()#Test4执行结果 #2、闭包,内层函数对外层函数非全局变量的引用称为闭包 #例: def Test6(): name = 'test6' def Test7(): print(name) Test7() print(Test7.__closure__)#判断函数区域是否是闭包,返回 <cell at *** 为闭包 Test6() #如函数内声明变量为全局,则不是闭包 def Test8(): global name #声明全局变量 name = 'Test8' def Test9(): print(name) Test9() print(Test9.__closure__)#返回None则表示不是闭包 Test8() #*使用:闭包所在的临时名称空间不会随函数执行完毕而消失,主要用在爬虫 def make(n): x = [] for i in range(n): x.append(lambda: print('i', i))#lambda 匿名函数,格式 lambda: 函数体 # print(x)#x[]里存的是匿名函数对象 return x a, b, c = make(3)#执行make函数,把 x 分别赋给a, b, c print(a) print(b) print(c) a(), b(), c()#执行x(匿名对象) → print('i', i) #函数的有用信息 def test(): """ 就测试一下 :return: T 成功, F 失败 """ print(test.__name__)#输出函数名 print(test.__doc__)#输出函数说明