第二章 函数
1. 函数式编程
本质:将N行代码拿到别处并起名,以后通过名字就可以找到这段代码并执行
场景:代码重复执行时和代码量特别多,超过一屏,可以选择通过函数进行代码的分割
2. 函数的基本结构
def 函数名(): #函数的定义
函数内容函数名() #执行函数
def func(): v = [11,22,33] print(0)func() #调用才会被执行,不调用则内部代码不会被执行
3. 函数的参数
基本的参数:可以传递任意个数,任意类型
#1.参数的基本结构def func(aaa): v = [11,22,33] print(v[aaa])func(1)#2.位置传参(调用函数并传入参数,传入参数和形参要一致)def func(a1,a2): #形参 print(a1,a2)func(1,2) #传参#3.关键字传参(关键字传参和位置传参可以混合使用,但位置参数一定要在前面,关键字参数在后面,两个参数之和等于形参)def func(a1,a2): print(a1,a2)func(1,a2=2)func(a2=1,a1=1) #关键字传参之间的顺序可以调换#4.默认参数def func(a1,a2=9): #接收两个或一个参数 print(a1,a2)func(1) #输出1,9func(1,2) #输出1,2#5.万能参数(不支持关键字传参,只能支持位置传参)例一:def func(*args): #可接受n个参数 print(args)func(11,22,33) #输出默认为元组func(*(1,2,3),*[11,22,33]) #把该元组/列表内的元素循环添加到新元组例二:def func(a1,*args): print(a1,args)func(1,2,3,4,5) #输出为 1,(2,3,4,5)#6.万能关键字参数(输出为字典,不支持位置传参)def func(**kwargs): print(kwargs)func(k1 =1,k2 = 'alex') #输出为{'k1':'v1','k2':'alex'}func(**{ 'k1':'v1','k2':'alex'}) #把自己输入的字典直接带入#7.万能综合应用def func(*args,**kwargs) print(args,kwargs)func(1,2,3,k1=1,k2=2) #输出为(1,2,3),{'k1':'1','k2':'2'}func(111,222,*[1,2],k11='alex',**{ 'k1':'1','k2':'2'}#输出为(111,222,1,2),{'k11':'alex','k1':'1','k2':'2'}
4.函数的返回值
定义:运行结束后进行返回一个值,默认return None
def func(arg): return 9###返回值为9val = func('Parallel')print(val) #打印9注:str和dict基本都有返回值,list无返回值,返回None
5.函数的嵌套和作用域
定义:作用域分为全局作用域和局部作用域,每一个函数都属于一个局部作用域,自己作用域中没有的参数可以向上级找,一直到全局作用域,没有则报错,但是不能向下级找。当子作用域要修改全局作用域的内容时,需要加关键字global+变量后再修改,修改上级时需要用nonlobal+变量再修改
6. 函数的赋值和函数当参数传递
#函数的赋值例一def func(): print(123)v1 = funcv1() #执行func函数v2 = [func,func]v2[0]() #执行函数v3 = { 'f1':func,'f2':func}v3['f1']() #执行函数#函数可以当作参数进行传递例二def func(arg): print(arg)def show(): return 999func(show) #打印999例二def func(arg): v1 = arg() print(v1)def show(): print(666)func(show) #在func中执行arg()时打印666,v1没有收到返回值打印None
7.函数当返回值传递
例一def func(): print(123)def bar(): return funcv = bar() #执行bar函数并给v返回func函数v() #执行func函数例二def func(): def inner(): print(123) return innerv = func() #执行func函数,返回inner函数给vv() #执行func中inner函数,打印123例三name = 'Parallel'def func(): print(name)def bar(): return funcv = bar()v() #当函数中没有name变量时,向全局中找例四name = 'Parallel'def func(): name = 'World' def inner(): print(name) return innerv = bar()v() #自己函数中没有的变量,优先从上级找,上级没有再向上级找
8.闭包
定义:为某一个函数开启一块区域(内部变量供自己使用)为他以后执行提供数据
name = 'oldboy'def bar(name): def inner() print(name) return innerv1 = bar('alex') #存储数据v2 = bar('eric') #存储数据v1() #alexv2() #eric
9. lambda 表达式
定义:常用与表示简单的函数,且无法自己创建变量,只能向上级搜索
例一def func(a1,a2): >>>>>>>>func=lambda a1,a2:a1+a2 return a1+a2 >>>>>>>>#func表示这个函数例二 可以和三元运算结合func = lambda n1,n2:n1 if n1>n2 else n2v = func(11,22)print(v) #22
10 内置函数
10.1 数学相关
abs() 绝对值
float() 浮点型(小数点)
max() 最大
min() 最小
sum() 求和
divemod() 相除得商和余数
#例题:利用divmod完成分页展示total_count = len(USER_LIST) #数据总条数per_page_count = 10 #每页显示10条max_page_num,a = divmod(total_count,per_page_count) #总页码数if a>0: max_page_num += 1pager = int(input("请输入要查看第几页"))if pager <1 or pager >max_pager_num: print('页码不合法,必须是1~%s'%max_page_num)else: start = (pager-1)* per_page_count end = pager * per_page_count data = USER_LIST[start:end] for item in data: print(item)
10.2 进制相关
bin():将十进制转换成二进制 v1 = bin(13)
oct():将十进制转换成八进制 v2 = oct(13)
int():将其他进制转换成十进制 v3 = int(0b1101,base=2) #2进制转成成10进制
hex():将十进制转换成十六进制 v4 = hex(13)
#例题:将IP'192.168.12.79'中的十进制转换成二进制后拼接算出十进制的值IP = '192.168.12.79'IP = IP.split('.')p = ''for y in IP: y = int(y) h = bin(y) c = str(h) if p == '': p = c else: if len(c)!= 10: c = c[2:len(c)] c = (8-len(c))*'0' + c else: c = c[2:len(c)] p = p+c h = int(p,base=2)print(h)
10.3 编码相关
chr():将内容转换成Unicode编码中对应的字符串
ord():将Unicode编码中找到对应的内容转换出来
#例题:生成随机验证码import randomdef get_random_cod(length=6): data=[] for i in range(6): v = random.randint(1,3) data.append(chr(v)) return ''.join(data)code = get_random_code()print(code)
11 装饰器
10.1 装饰器定义和应用场景
定义:当函数遇到装饰器时,首先要执行装饰器函数,之后再执行原函数
应用场景:想要为函数扩展功能时,在不改变原函数的基础上,可以选择用装饰器
10.2 装饰器编写格式和应用格式
#编写格式def 外层函数(参数): def 内层函数(*args,**kwargs): return 参数(*args,**kwargs) return 内层函数#应用格式@外层函数def index(): passindex()
10.3 带参数的装饰器
list = []def m1(counter): def wrapper(func): def inner(*arg, **kwargs): for i in range(counter): list.append(func()) return list return inner return wrapper@m1(5)def func(): return 8v = func()print(v)
12 推导式
列表/集合/字典推导式:方便生成一个列表、集合或字典,
列表/集合格式:v1 = [i for i in 可迭代对象] #生成列表
v2 = [99 i if i > 5 else 66 for i in range(10)] #添加判断生成列表
v3 = [i for i in range(10) if i > 5] #先筛选后生成列表
字典格式:v4 = {'k' + str(i):i for i in range(10)}
13 递归
函数自己调用自己(效率低)
例1:
def f1():
pass
def f2():
f1()
f2()
例2:
def f1():
print(1)
f1()
f1()
例题:递归函数与三级菜单
#三级菜单menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {},}
#递归函数实现三级菜单def threeLM(dic): while True: for k in dic:print(k) key = input('input>>').strip() if key == 'b' or key == 'q':return key elif key in dic.keys() and dic[key]: ret = threeLM(dic[key]) if ret == 'q': return 'q'#堆栈实现三级菜单l = [menu]while l: for key in l[-1]:print(key) k = input('input>>').strip() # 北京 if k in l[-1].keys() and l[-1][k]:l.append(l[-1][k]) elif k == 'b':l.pop() elif k == 'q':break