1、模拟一个len函数实现
#重复代码多,可读性差
li = {1,2,3,4,'alex'} count = 0 for i in li: count += 1 print(count)
#测量字符串长度
s1 = '12321321312312312'
count = 0
for i in s1:
count += 1
print(count)
2、函数的初识
def 关键字 函数名(设定与变量相同):
函数体
函数名()执行函数
1.#函数的返回值 return
只有两个作用:
1、遇到return,结束函数。
def func1():
print(11)
print(22)
return
print(33)
func1()
2、给函数的调用者(执行者)返回值
无return返回none
有return或者不写返回none 结束def下的返回
return count 返回单个数
return 多个数据是将多个数据放在一个元组里返回
1 s1 = '1231221321321321' 2 def my_len(): 3 count = 0 4 for i in s1: 5 count += 1 6 # print(count) 7 return count,222,444 8 ret1,ret2,ret3 = my_len() 9 print(ret1) 10 print(ret2) 11 print(ret3)
2、函数的传参
参数分为:形参和实参,实参就是实际参数,形参就是函数里面的形式参数
1 s1 = '1231221321321321' 2 def my_len(a): #函数的定义()放的是形式参数,形参 3 count = 0 4 for i in a: 5 count += 1 6 # print(count) 7 return count 8 ret = my_len(s1) #函数的执行()实际参数,实参 9 print(ret)
传参的大方向
实参角度来说分为:1.位置参数 2.关键字参数 3.混合参数
形参角度来说分为:1.位置参数 2.默认参数 3.万能参数
1 #1、位置参数,必须一一对应,按顺序 2 def func1(x,y): # 1,2对应x,y。 3 print(x,y) 4 func1(1,2) 5 # #2、关键字参数,不分顺序,但是一一对应 6 def func1(x,y,z): 7 print(x,y,z) 8 func1(y=1,x=2,z=5) 9 #3、混合参数,关键字参数必须要在位置参数的后边,一一对应 10 def func2(argv1,argv2,argv3): #既有位置参数又有关键字参数就是混合参数 11 print(argv1) 12 print(argv2) 13 print(argv3) 14 func2(1,2,argv3=4) 15 #练习:函数接收两个数,比大小, 把大的返回 16 def func1(x,y): 17 if x > y: 18 return x 19 else:return y 20 print(func1(1,2)) 21 #引申三元表达式 22 def func1(x,y): 23 ret= x if x > y else y 24 print(func1(1,2))
#简单的函数定义可以用三元表达式 25 def func1(x,y):return x if x > y else y 26 print(func1(1,2)) 27 #从形参角度 28 #1、位置参数,跟实参一样,一一对应 29 def func1(x,y): 30 print(x,y) 31 func1(1,2) 32 #2、默认参数 必须在位置参数后边。 33 def register(name,sex='男'): 34 with open('register',encoding='utf-8',mode='a') as f1: 35 f1.write('{} {}\n'.format(name,sex)) 36 while True: 37 name = input('请输入姓名:/q or Q 退出').strip() 38 if name.upper() == 'Q':break 39 if 'a' in name: 40 sex = input('请输入性别:').strip() 41 register(name,sex) 42 else:register(name) 43 #3、动态参数,*args,**kwargs 万能参数,把位置参数,关键字参数都传进函数里。 44 def func2(*args,**kwargs): 45 print(args) #元组(所有位置参数) 46 print(kwargs)#字典(接收所有关键字参数放到一个字典里。) 47 func2(1,2,3,4,55,6,7,88,232,'alex','laoadsa',a='11',b='22') 48 #4、位置参数,默认参数,万能参数的位置比较(顺序) 49 #**********位置参数,*args,默认参数,**kwargs 50 def func3(a,b,*args,sex='nan',**kwargs): 51 print(a) 52 print(b) 53 print(sex) 54 print(args) 55 func3(1,2,'laonanhai','alex','wusir',sex='女') 56 def func1(*args,**kwargs): #函数的定义 * 聚合功能,将实参的位置参数聚合到一个 57 print(args) 58 print(kwargs) 59 l1 = [1,2,34,5] 60 l2 = [3123,21,313,1] 61 func1(*l1,*l2) #函数的执行,* 打散功能,把所有列表或者元组的元素打散 62 # (1, 2, 34, 5, 3123, 21, 313, 1) 63 def func1(*args,**kwargs): 64 print(args) 65 print(kwargs) 66 dic1 = {'name1':'alex','name2':'laonanhai'} 67 dic2 = {'name4':'alex','name3':'laonanhai'} 68 func1(**dic1,**dic2) 69 # {'name1': 'alex', 'name2': 'laonanhai', 'name4': 'alex', 'name3': 'laonanhai'}
3. 函数的进阶
1.名称空间
name = 'alex'
age = 12
当程序运行的时候,在内存中创建一个名称空间,也叫命名空间,
里面存着变量与值得内存地址的关系,如下图:
![](https://images2018.cnblogs.com/blog/1366459/201804/1366459-20180418140746820-1138701619.png)
2.临时名称空间,也叫局部名称空间,存入函数里面的变量与值的关系,随着函数的执行结束,
临时名称空间消失
def func1():
name1 = 'wusir'
age = 34
func1()
3.内置名称空间,比如len()解释器只要一加载内置名称空间就存在了
4.作用域:全局作用域(全局名称空间,内置名称空间),局部作用域(局部名称空间)
5.加载顺序,取值顺序
加载:内置名称空间>全局名称空间>局部名称空间(函数执行时)
取值:局部名称空间(函数执行时)>全局名称空间>内置名称空间
取值顺序例子:
name1 = 'wusir'
def func1():
name1 = 'alex'
print(name1)
def func2():
name1 = 'taibai'
print(name1)
func2()
func1()
6.globales locals打印出全局名称空间和局部名称空间的变量打印出来,放到一个列表当中
name1 = 'wusir'
def func1():
name2 = 'laonanhai'
print(globals())
print(locals())
return locls()
func1()
7.关键字:global nonlocal
count = 'alex'
def func1():
count += 1 #局部名称空间可以引用全局名称空间,不可以改变
print(count)#报错
func1()
global : 声明一个全局变量,如果存在可以更改全局变量
name = ‘wusir’
def func1():
global name #在局部名称空间声明一个全局变量,更改全局变量
name = 'alex'
return
func1()
print(name)
nonlocal:不能修改全局变量,从父级引用变量,并改变从父层开始后续所有变量都改变。
def func1():
name1 = 'alex'
print(name1)
def inner():
nonlocal name1
name1 = 'wusir'
print(name1)
inner()
print(name1)
func1()
4.函数名
#1,可以互相赋值 def func1(): print(666) f1 = func1 f1()
#2.函数名可以当成函数的参数 def func1(): ptint(666) def func2(argv): argv() print(777) func2(func1)
#3.函数名可以当成容器类数据类型的参数 def func1(): print(666) def func2(): print(777) def func3(): print(888) l1 = [func1, func2, func3] for i in l1: i()
#4.函数名可以当成函数的返回值 def func1(): print(666) def func2(argv): print(777) return argv ret = func2(func1) = func1#看到=先算右边 ret()
5.闭包 内层函数对外层函数非全局变量的引用,叫做闭包
def wrapper(): name1 = 'laonanhai' def inner(): print(name1) inner() wrapper()
#判断是不是闭包 def wrapper(): name1 = 'laonanhai' def inner(): print(name1) inner() print(inner.__closure__)#cell wrapper()
#闭包的好处,如果python检测到闭包,他有一个机制,你的局部作用域不会随着函数的结束而结束
#可以保存缓存到内存
6.装饰器
def wrapper(f1): def inner(*args,**kwargs): '''执行函数之前的操作''' ret = f1(*args,**kwargs) '''执行函数之后的操作''' return ret return f1