第二章 函数
第二章 函数
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,9 func(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###返回值为9 val = func('Parallel') print(val) #打印9 注:str和dict基本都有返回值,list无返回值,返回None
5.函数的嵌套和作用域
定义:作用域分为全局作用域和局部作用域,每一个函数都属于一个局部作用域,自己作用域中没有的参数可以向上级找,一直到全局作用域,没有则报错,但是不能向下级找。当子作用域要修改全局作用域的内容时,需要加关键字global+变量后再修改,修改上级时需要用nonlobal+变量再修改
6. 函数的赋值和函数当参数传递
#函数的赋值 例一 def func(): print(123) v1 = func v1() #执行func函数 v2 = [func,func] v2[0]() #执行函数 v3 = {'f1':func,'f2':func} v3['f1']() #执行函数 #函数可以当作参数进行传递 例二 def func(arg): print(arg) def show(): return 999 func(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 func v = bar() #执行bar函数并给v返回func函数 v() #执行func函数 例二 def func(): def inner(): print(123) return inner v = func() #执行func函数,返回inner函数给v v() #执行func中inner函数,打印123 例三 name = 'Parallel' def func(): print(name) def bar(): return func v = bar() v() #当函数中没有name变量时,向全局中找 例四 name = 'Parallel' def func(): name = 'World' def inner(): print(name) return inner v = bar() v() #自己函数中没有的变量,优先从上级找,上级没有再向上级找
8.闭包
定义:为某一个函数开启一块区域(内部变量供自己使用)为他以后执行提供数据
name = 'oldboy' def bar(name): def inner() print(name) return inner v1 = bar('alex') #存储数据 v2 = bar('eric') #存储数据 v1() #alex v2() #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 n2 v = 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 += 1 pager = 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 random def 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(): pass index()
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 8 v = 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()
例题:递归函数与三级菜单
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#三级菜单 menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {}, }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#递归函数实现三级菜单 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