函数
函数定义:
函数是指将一组语句的集合通过一个名字封装起来,要想执行这个函数只需要调用其函数名即可.
函数特性:
1.减少重复代码
2.使程序变的可扩展性
3.使程序变的易维护
函数语法定义:
def name(): # 函数名 print('hello, world') name() # 调用
带参数的函数
# 下面这段代码 a,b = 5,8 c = a**b print(c) # 改成用函数写 def calc(x,y): res = x**y return res # 返回函数执行结果 c = calc(a,b) # 结果赋值给c变量 print(c)
函数参数:
形参:只有在被调用的才分配内存单元,在调用结束时,即刻释放所分配的内存单元.因此,形参只在函数内部有效,函数调用结束后返回主调用函数后不能再使用该形参变量.
实参:可以是常量,变量,表达式,函数等.无论实参是何种类型的量,在进行函数调用时,它都必须有确定的值以便把这些值传给形参,因此应预先用赋值,输入等办法使参数获得确定值
位置参数:
在调用的时候必须和参数位置顺序对应
def stu_register(name, age, country, course): print("----注册学生信息------") print("姓名:", name) print("age:", age) print("国籍:", country) print("课程:", course) stu_register("王山炮", 22, "CN", "python") stu_register("张叫春", 21, "CN", "linux") stu_register("刘老根", 25, "CN", "linux")
默认参数:
country在参数中定义了值,这个参数在调用时不指定,那默认就是CN,指定了的话,就用你指定的值.
def stu_register(name, age, course, country='CN'): print("----注册学生信息------") print("姓名:", name) print("age:", age) print("国籍:", country) print("课程:", course) stu_register("王山炮", 22, "python") stu_register("张叫春", 21, "linux") stu_register("刘老根", 25, "linux", 'Korean') # 调用的时候不写country默认为CN
关键参数:
调用的时候不想按顺序就可以用关键参数,注意的是,关键参数必须放在位置参数之后
def stu_register(name, age, course='PY', country='CN'): print("----注册学生信息------") print("姓名:", name) print("age:", age) print("国籍:", country) print("课程:", course) stu_register("王三炮", course="PY", age=22, country="China") # 调用的时候不想按顺序就可以用关键参数
非固定参数:
*args
如果参数中出现*args,传递的参数就可以不再是固定参数,传过来的所有参数打包成元祖形式.
def stu_register(name, age, *args): # *args 会把多传入的参数变成一个元组形式 print(name, age, args) stu_register("Alex", 22) # 输出:Alex 22 (),后面这个(),就是args,只是因为没传值,所以为空 stu_register("Jack", 32, "Linux", "Go") # 输出:Jack 32 ('Linux', 'Go')
如果 调用方法的时候,*args传入["Linux", "Go"],打印结果:(["linux"])---->*args传入*["Linux", "Go"],打印结果("Linux", "Go")
**kwargs
如果参数中出现**kwargs,传递的参数就可以不再试固定个数,传过来的所有参数打包成字典形式
def stu_register(name, age, *args, **kwargs): # *kwargs 会把多传入的参数变成一个dict形式 print(name, age, args, kwargs) stu_register("Alex", 22) # 输出:Alex 22 () 后面这个{}就是**kwargs,只是因为没传值,所以为空 stu_register("Jack", 32, "CN", "Python", sex="Male", province="ShanDong") # 输出:Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}
def stu_register(name, age, *args, **kwargs): # *kwargs 会把多传入的参数变成一个dict形式 print(name, age, args, kwargs) stu_register("Alex", 22) # 输出:Alex 22 () 后面这个{}就是**kwargs,只是因为没传值,所以为空 d = {'degree': 'primary school'} stu_register('王小二', 8, 'python', **d) # 输出:王小二 8 ('python',) {'degree': 'primary school'}
定义:d = {'degree': 'primary school'},如果调用方法的时候,传入stu_register('王二小', 8, d),打印:王二小 8 ({'degree': 'primary school'},) {}--->**d,输出字典王二小 8 () {'degree': 'primary school'}
函数的返回值:
def stu_register(name, age, course): print(name, age, course) if age > 22: return False else: return [name, age] # 默认返回元祖,加上指定类型返回该类型数据 status = stu_register('ike', 20, 'Python') print(status)
# 输出
ike 22 Python
['ike', 22]
注:函数在执行过程中只要遇到return语句,就会停止执行并返回结果,所以也可以理解为 return 语句代表着函数的结束
如果为在函数中指定return,那这个函数的返回值为None
局部与全局变量:
局部变量就是指定义在函数里的变量,只能在局部生效.
全局变量就是指在函数外部一级代码的变量,叫做全局变量,全局都能用.
注:在函数内部,可以引用全局变量,如果全局和局部都有一个变量,叫name,函数会查找的顺序,由内而外.
name = '函数外边' # 局部变量-->函数里面定义的变量--函数里print从里到外找name def change_name(): name = '函数里边' print('在', name, id(name)) change_name() print(name, id(name))
局部golbal可以修改全局变量
name = '函数外边' # 局部变量-->函数里面定义的变量--函数里print从里到外找name def change_name(): global name name = '函数里边' print('在', name, id(name)) change_name() print(name, id(name))
# 打印结果
在 函数里边 10435328
函数里边 10435328
函数内部有del方法,全局变量相应删除
name = ['黑姑娘', 'alex', 'pei qi'] # 局部变量-->函数里面定义的变量--函数里print从里到外找name def change_name(): del name[0] # name = ['pei qi', 'alex'] print('在', name, '里边...', id(name)) change_name() print(name, id(name))
嵌套函数:
1.函数内部可以再次定义函数
2.执行需要被调用(内部也需要调用)
func0 = 'ike' def func1(): print('alex') def func2(): print('jack') func2() func1() print(func0)
函数里边的age = 73,分别放在调用最里层的函数上下输出
age = 19 def func1(): global age def func2(): print(age) age = 73 # 放在调用func2()最里层下边,打印 19 73, 放在调用func2()上边,打印 73 73 func2() func1() print(age)
作用域:
作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
匿名函数:
1.节省代码量
2.看着高级
data = list(range(10)) print(data) print(list(map(lambda x: x*x, data)))
def calc(x, y): if x > y: return x*y else: return x/y # 声明一个匿名函数 等同与上边的函数 func = lambda x, y: x*y if x < y else x/y print(func(3, 8))
print(list(map(lambda x: x*x if x > 5 else x, range(10))))
高阶函数:
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def func(x, y): return x, y def calc(x): return x f = calc(func) print(f(5, 9))
def add(x, y, f): return f(x) + f(y) res = add(3, -6, abs) print(res)
满足以下任意一个条件,即是高级函数
1.接收一个或多个函数作为输入
2.return返回另外一个函数
递归:
在函数内部,可以调用其他函数。如果一个函数在内部调用自己本身,这个函数就是递归函数。
def calc(n): print(n) if int(n/2) ==0: return n return calc(int(n/2)) calc(10) 输出 10 5 2 1
递归的特征:
1.必须有一个明确的结束条件
2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数
调用是通过栈(stack)这种数据结构实现的,每当进入一个函数
调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。
由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
# 阶乘 def factorial(n): if n == 1: # 有一个明确的结束条件 return 1 return n * factorial(n-1) # 2+6+12 print(factorial(7))
尾递归
def cal(n): print(n) return cal(n+1) cal(1)
return的数据和上一层没有任何的关系.
内置函数: