函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需要调用其函数名即可。
特性:
1、减少重复代码
2、使程序变得可扩展
3、使程序变得易维护
语法定义:
1 def sayhi(): # 函数名 2 print("hello,I‘m nobody!") 3 4 sayhi() # 调用函数
参数可以让函数更灵活,不止能做死的动作,还可以根据调用时传参的不同来决定函数内部的执行流程
1 def calc(x,y): 2 res = x**y 3 return res # 返回函数执行结果 4 5 a,b = 3,5 6 c = calc(a,b) # 结果赋值给c变量 7 print(c)
形参变量:
只有只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元,因此,形参只在函数内部有效。
函数调用结束返回主调用函数后则不能再使用该形参变量
实参:
可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,他们都必须有确定的值,以便把这些值传给形参
因此,应预先用赋值、输入等办法使参数获得确定值
def calc(x,y): # x,y 是形参 res = x**y return res a,b = 3,5 c = calc(a,b) # a,b 是实参 print(c)
默认参数:
1 def stu_register(name,age,country,course): 2 print("------注册学生信息--------") 3 print("姓名:", name) 4 print("age:", age) 5 print("国籍:", country) 6 print("课程:", course) 7 8 stu_register("望山跑",22,"CN","python_develop") 9 stu_register("张三",21,"CN","linux") 10 stu_register("刘老根",25,"CN","linux") 11 12 # 参数country基本都是“CN”,就可以把country设为默认参数 13 14 def stu_register(name,age,course,country="CN"): 15 print("------注册学生信息--------") 16 print("姓名:", name) 17 print("age:", age) 18 print("国籍:", country) 19 print("课程:", course) 20 21 stu_register("望山跑",22,"python_develop") # 调用时不指定,默认就是CN 22 stu_register("张三",21,"linux") 23 stu_register("刘老根",25,"linux",country="U.S.") # 调用时指定,就是指定值
关键参数:
正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需要指定函数名即可(指定了参数名的参数就叫关键参数)
关键参数必须放在位置参数(以位置顺序确定对应关系的参数)之后
1 def stu_register(name,age,course="PY",country="CN"): 2 print("------注册学生信息--------") 3 print("姓名:", name) 4 print("age:", age) 5 print("国籍:", country) 6 print("课程:", course) 7 8 stu_register("zhang",23,course="python",country="DE") 9 stu_register("张三",country="KSA",course="linux",age=22) 10 # stu_register("张三",country="UK",22,course="linux") # 报错 关键参数在位置参数之前 11 # stu_register("zhangsan",22,age=22,country="KOR") # 报错 给age赋两次值
非固定参数:
若函数定义时不确定用户想传入多少个参数,可以使用非固定函数
1 def stu_register(name,age,*args): # *args会把多传入的参数变成一个元组形式 2 print(name,age,args) 3 4 stu_register("alex",22) 5 # 输出 6 # alex 22 () # 最后这个()就是args,因为没传值,所以是空 7 8 stu_register("Jack",23,"CN","linux") 9 # 输出 10 # Jack 23 (‘CN‘, ‘linux‘) 11 12 13 def stu_register(name,age,*args,**kwargs): # *kwargs会把多传入的参数变成一个dict 14 print(name,age,args,kwargs) 15 16 stu_register("alex",22) 17 # 输出 18 # alex 22 () {} # 后面的{}就是kwargs,因为没值,所以为空 19 20 stu_register("jack",23,"CN","python",sex="male",province="shandong") 21 # 输出 22 # jack 23 (‘CN‘, ‘python‘) {‘sex‘: ‘male‘, ‘province‘: ‘shandong‘}
函数外部的代码要想获取函数的执行结果,就可以在函数里用return语句把结果返回
1 def stu_register(name,age,course="PY",country="CN"): 2 print("------注册学生信息--------") 3 print("姓名:", name) 4 print("age:", age) 5 print("国籍:", country) 6 print("课程:", course) 7 if age > 22: 8 return False 9 else: 10 return True 11 12 registriation_status = stu_register("zhang",23,course="linux",country="UK") 13 14 if registriation_status: 15 print("注册成功") 16 else: 17 print("too old to be a student....")
注意:
1、函数在执行过程中只要遇到return语句,就会停止执行并返回结果,可以理解为return语句代表着函数的结束
2、如果未在函数中指定return,那这个函数的返回值为None
1 name = "Alex Li" 2 3 def change_name(name): 4 print("before change:",name) 5 name = "金角大王" 6 print("after change:",name) 7 8 change_name(name) 9 10 print("在外面看看name改了吗?",name) 11 12 # 输出 13 # before change: Alex Li 14 # after change: 金角大王 15 # 在外面看看name改了吗? Alex Li
1 # 不用传name值到函数里,也可以在函数里调用外面的变量 2 name = "Alex Li" 3 4 def change_name(): 5 name = "金角大王" 6 print("after change:",name) 7 8 change_name() 9 10 print("在外面看看name改了吗?",name) 11 12 # 输出 13 # after change: 金角大王 14 # 在外面看看name改了吗? Alex Li
函数内部对变量的更改对函数外的变量无影响
在函数中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量
全局变量作用域是整个程序,局部变量作用域是定义该变量的函数
当全局变量与局部变量同名时,在定义局部变量的函数内,局部变量起作用;在其他地方,全局变量起作用
作用域(scope):
程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域
如何在函数里修改全局变量
1 name = "Alex Li" 2 3 def change_name(): 4 global name 5 name = "金角大王" 6 print("after change:",name) 7 8 change_name() 9 10 print("在外面看看name改了吗?",name) 11 12 # 输出 13 # after change: 金角大王 14 # 在外面看看name改了吗? 金角大王 15 16 # global name 的作用就是要在函数里声明全局变量name,意味着最上面的name = "Alex Li"即使不写,程序最后面的print也可以打印name
在最外层无法调用内层函数
1 name = "alex" 2 3 def change_name(): 4 name = "alex2" 5 6 def change_name2(): 7 name = "alex3" 8 print("第3层打印:",name) 9 10 change_name2() # 调用内层函数 11 print("第2层打印:",name) 12 13 change_name() 14 print("最外层打印:",name) 15 16 # change_name2() # NameError: name ‘change_name2‘ is not defined 17 18 # 输出 19 # 第3层打印: alex3 20 # 第2层打印: alex2 21 # 最外层打印: alex
匿名函数就是不需要显式的指定函数名,主要和其他函数搭配使用
1 def calc(x,y): 2 return x**y 3 4 print(calc(2,5)) 5 6 # 匿名函数 7 8 calc = lambda x,y:x**y 9 print(calc(2,5))
1 # 和其他函数搭配 2 res = map(lambda x:x**2,[1,3,5,7,9]) 3 for i in res: 4 print(i)
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数
满足以下任意一个条件,既是高阶函数:
接受一个或多个函数作为输入
return返回另外一个函数
1 def add(x,y,f): 2 return f(x) + f(y) 3 4 res = add(3,-6,abs) 5 print(res)
在函数内部,可以调用其他函数,如果一个函数在内部调用自己本身,这个函数就是递归函数
1 def calc(n): 2 print(n) 3 if int(n/2) == 0: 4 return n 5 return calc(int(n/2)) 6 7 calc(10) 8 9 # 输出 10 # 10 11 # 5 12 # 2 13 # 1
1 def calc(n): 2 v = int(n/2) 3 print(v) 4 if v > 0: 5 calc(v) 6 print(n) 7 8 calc(10) 9 10 # 输出 11 # 5 12 # 2 13 # 1 14 # 0 15 # 1 16 # 2 17 # 5 18 # 10
递归特性:
1、必须有一个明确的结束条件
2、每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3、递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以递归调用的次数过多,会导致栈溢出)
递归用途:
解决很多算法问题,把复杂的问题分成一个个小问题,一一解决
# 二分查找 data = [1,3,4,6,7,9,11,13,14,18,21,23,25,27,30,32,37] def binary_search(dataset,find_num): print(dataset) if len(dataset) > 1: mid = int(len(dataset)/2) if dataset[mid] == find_num: # find it print("找到数字",dataset[mid]) elif dataset[mid] > find_num: # 要找的数比中间数小,即,在mid左边 print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid]) return binary_search(dataset[0:mid],find_num) else: # 找的数在mid右面 print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid]) return binary_search(dataset[mid+1:],find_num) else: if dataset[0] == find_num: # find it print("找到数字啦",dataset[0]) else: print("没得分了,要找的数字[%s]不在列表里" % find_num) # binary_search(data,66) binary_search(range(101),66)
1 # 阶乘 2 # n! = n * (n-1)! # 任何大于1的自然数n阶乘表示方法 3 4 def factorial(n): 5 # if n > 0: 6 # return n * factorial(n-1) 7 # else: 8 # return 1 9 if n == 0: # 是0的时候,就运算完了 10 return 1 11 return n * factorial(n-1) # 每次递归相乘,n值都较之前小1 12 13 print(factorial(5))
详解: https://docs.python.org/3/library/functions.html?highlight=built#ascii
1 # help() # 帮助 2 3 # all(i) # iterable 如果i中所有值都为真,返回True,如果i为空,返回True 4 print(all([0,1])) # False 5 # any(i) # 如果i中任一值为真,返回True,如果i为空,返回False 6 print(any([0])) # False 7 8 # ord(‘a‘) # 返回表示该字符的Unicode代码点的整数 9 # chr(97) # 由ASCII对应位置找到元素 10 # ascii(o) # 非ASCII码会转成Unicode 11 12 # hex() # 把一个数转成十六进制 13 # oct() # 转成八进制 14 # bin() # 二进制 15 16 # dict() # 转换成字典 17 # bool() # 判断一个值的真假 18 # int() 19 # str() 20 # float() 21 # tuple() 22 # list() 23 # set() 24 # frozenset() # 不可变集合 25 # bytes() 26 # id() 27 # format() 28 # len() 29 # type() 30 31 # abs(n) # 返回绝对值 32 # min() # 列表里取最小值 33 # max() # 最大值 34 # complex() # 变成复数 35 print(complex(3,5)) # (3+5j) 36 # round() # 保留几位小数 37 print(round(1.832433)) # 2 38 print(round(1.832433,3)) # 1.832 39 # sum() # 求和 40 # divmod(x,y) # 返回元组(商,余数) 41 print(divmod(10,3)) # (3, 1) 42 # pow(x,y) # x**y 43 44 # range() 45 # enumerate # 枚举 46 # hash() # 哈希 47 48 # dir() # 打印当前程序所有变量 49 # vars() # 当前所有变量,和变量的值 50 # locals() # 一般函数内部使用,打印函数的局部变量 51 # globals() # 打印全局变量 52 53 # slice() # 切片 54 >>>l = list(range(10)) 55 >>>s = slice(1,7,2) 56 >>>l[s] # 相当于预先制定好切片规则 57 58 # sorted() # 排序 59 # reversed() # 默认反转 60 l = [1,3,6,4,9,2] 61 print(sorted(l)) 62 63 d = {} 64 for i in range(20): 65 d[i] = i-50 66 print(d) 67 68 d[10] = 99 69 print(sorted(d.items(),key=lambda x:x[1])) # 按value排序 70 print(sorted(d.items(),key=lambda x:x[1],reverse=True)) 71 72 # input() 73 # print() # print(self, *args, sep=‘ ‘, end=‘\n‘, file=None) 74 for i in range(5): 75 print(i) 76 print(i,end=‘,‘) # 0,1,2,3,4, 77 78 print(‘abc‘,‘123‘) # abc 123 默认是‘ ‘ 79 print(‘abc‘,‘123‘,sep=‘--‘) # abc--123 80 81 msg = "又回到最初的起点" 82 f = open(‘print_test‘,‘w‘,encoding=‘utf-8‘) 83 print(msg,"jiyizhong你青涩的脸",sep=‘|‘,end=‘‘,file=f) 84 print(msg,"jiyizhong你青涩的脸",sep=‘|‘,end=‘‘,file=f) 85 86 # open() 87 88 # eval() # 处理单行代码 可以拿到返回值 89 f = "1+3/2" 90 print(eval(f)) 91 # exec() # 可以处理多行代码 但拿不到返回值 92 93 # memoryview() # 大数据copy用 94 # bytearray() # 字符串变成bytearrary后,可以修改 95 s = ‘abcd路飞‘ 96 print(s[0]) # a 97 # s[0]=‘f‘ TypeError: ‘str‘ object does not support item assignment 98 s2 = bytearray(s.encode(‘utf-8‘)) 99 print(id(s2)) # 2309116684920 100 print(s2[0]) # 97 101 s2[0]=65 102 print(s2) # bytearray(b‘Abcd\xe8\xb7\xaf\xe9\xa3\x9e‘) 103 s2[4]=235 104 print(s2.decode()) # Abcd?飞 105 print(id(s2)) # 2309116684920 106 107 # map() # 108 # filter() # 过滤 109 # reduce() # 在functools中 110 s = map(lambda x:x*x,[1,2,3,4,5]) 111 print(list(s)) # [1, 4, 9, 16, 25] 112 s = filter(lambda x:x>3,[1,2,3,4,5]) 113 print(list(s)) # [4, 5] 114 115 import functools 116 s = functools.reduce(lambda x,y:x+y,[1,3,45,34,7,8]) # 98 117 s = functools.reduce(lambda x,y:x*y,[1,3,45,34,7,8]) # 257040 118 print(s) 119 s1 = functools.reduce(lambda x,y:x+y,[1,3,45,34,7,8],9) # 107 120 print(s1) 121 122 # callable() # 判断是否可调用 给一个变量,判断是否是函数 123 def f(): 124 pass 125 126 print(callable(f)) # True 127 128 # repr() 129 130 # zip() 131 a = [1,3,5,0,-2] 132 b = [‘a‘,‘b‘,‘c‘] 133 print(list(zip(a,b))) # [(1, ‘a‘), (3, ‘b‘), (5, ‘c‘)] 134 135 # setattr() # 后面讲 136 # getattr() 137 # hasattr() 138 # delattr() 139 # next() 140 # object() 141 # staticmethod() 142 # isinstance() 143 # issubclass() 144 # super() 145 # iter() 146 # property() 147 # classmethod() 148 # compile() # 编译代码用 149 # __import__() # 模块用
原文:https://www.cnblogs.com/wuyinglianjianjue/p/10332195.html