python_函数
定义:
计算机中函数跟数学中的函数不一样,计算机函数指的是提前组织好的,可重复使用的一段子程序,或者说是一段可执行的代码过程。
作用:
1、提高代码的模块性,提高代码的重复利用性。
2、减少重复代码
3、便易扩展(增加或删除功能)
4、保持代码的一致性
语法:
python中用 def 来定义一个函数,格式如下:
1 def 函数名(参数列表): 2 函数体
3 函数名(参数列表) #调用和执行函数
函数名的定义与变量的命名一样:
必须是字母或是下滑线开头
不能使用其他特殊符号
区分大小写
不能使用python内部的保留字
实例演示:
1 def Hello(): 2 print("hello word!") 3 4 Hello() #函数的调用
形参和实参:
1 def cal(x,y): #这个x,y为形参(形式参数) 2 print(x+y) 3 4 cal(3,8) #这的参数叫实参(实际的参数)
>>>11
形参是函数定义里的形式参数,实参是函数调用时传入的实际参数,参数的顺序是由严格顺序的。
函数的参数:
位置参数:
传入的实参跟形参是一一对应的
1 def print_info(Name,Age): 2 print("name:%s"%Name) 3 print("age:%d"%Age) 4 5 6 print_info("Adair",18)
默认参数:
若有参数不需要经常变化,可以在形参的位置把该参数指定上
def print_info(Name,Age=18): print("name:%s"%Name) print("age:%d"%Age) print_info("Adair")
注:默认参数必须在位置参数后边
若默认参数需要变化时,可以在实参上直接修改,
def print_info(Name,Age=18): print("name:%s"%Name) print("age:%d"%Age) print_info("Adair",33) >>>name:Adair age:33 def print_info(Name,Age=18): print("name:%s"%Name) print("age:%d"%Age) print_info("Adair",Age=22) >>>name:Adair age:22
注:默认参数必须指向不变对象!
可变参数:
如果在调用参数传入的实参个数不确定,就可以使用可变参数。可变参数用一个 ( * )星号表示。
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
def Adder(*n): sum=0 for i in n: sum = sum + i print(sum) Adder(1,2,3,4,5,6) >>>21
1 def Adder(*n): 2 sum=0 3 for i in n: 4 sum = sum + i 5 print(sum) 6 7 num=[1,2,3,4,5,6] 8 Adder(*num) 9 10 >>>21
一个( * )星号,可以把列表和元组的元素当成可变参数当作实参传到函数中
关键字参数:
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def registered(name,age,**kw): print("name:",name) print("age:",age) print("hobby:",kw) registered("Adair",12,outdoor="basketball",indoor="swimming") >>>name: Adair age: 12 hobby: {'outdoor': 'basketball', 'indoor': 'swimming'}
1 def registered(name,age,**kw): 2 print("name:",name) 3 print("age:",age) 4 for i in kw: 5 print("%s:%s" %(i,kw[i])) 6 7 registered("Adair",12,outdoor="basketball",indoor="swimming") 8 9 >>>name: Adair 10 age: 12 11 outdoor:basketball 12 indoor:swimming
参数的组合:
参数定义的顺序必须是:位置参数、默认参数、可变参数、命名关键字参数和关键字参数。
1 def registered(name,age,*w,gender="M",**kw): 2 print("name:",name) 3 print("age:",age) 4 print("gender:",gender) 5 print("hobby:",w) 6 for i in kw: 7 print("%s:%s" %(i,kw[i])) 8 9 registered("Adair",12,"basketball","swimming",Nativeplace="北京",property="One hundred million") 10 11 >>>name: Adair 12 age: 12 13 gender: M 14 hobby: ('basketball', 'swimming') 15 Nativeplace:北京 16 property:One hundred million
函数的返回值(return):
return语句是python函数的一个返回值,每个函数中都应该有一个返回值,若没写python会自动返回一个None
当函数运行过程中与到return函数就会退出并返回值,也可以理解为return语句代表这函数的结束
return多个对象的时候,python会将其封装成一个元组进行返回
1 def Ret(): 2 print("asd") 3 return 1 4 5 print(Ret())
函数的作用域:
python中的作用域分为4层:
local:局部作用域,即函数中定义的作用域。
enclosing:嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
globa,全局作用域,就是模块级别定义的变量;
built-in,系统固定模块里面的变量,比如int, bytearray等。
搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。
python中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,像if、try、for这些是不存在作用域的
1 num = int(23.4) #built-in 内置作用域 2 name="Adair." #glocal 全局作用域 3 def scope(): 4 scope="test" #enclosing 外层作用域 5 def x_scope(): 6 x_scope="Test" #local 作用域局部
函数内部可以读取函数外部的变量,但不能直接修改,想要在函数内部修改外部变量时需要使用glocal关键字先声明一下。
1 num = 111 2 def scope_test(): 3 print(num) 4 5 scope_test() 6 >>>111 7 8 9 num = 111 10 def scope_test(): 11 global num 12 num+=222 13 print(num) 14 15 scope_test()
global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了
1 def scope_test(): 2 global num 3 a=222 4 print(a) 5 def x_scope(): 6 nonlocal a 7 a+=333 8 print(a) 9 x_scope() 10 scope_test()
11 >>>222
555
高阶函数:
把函数作为参数传入,这样的函数称为高阶函数。
1 def foo(n): 2 return n 3 4 def add(a,b,f): 5 return f(a)+f(b) 6 7 print(add(2,3,foo)
1、函数名可以进行赋值
2、函数名可以作为函数的参数,也可以作为函数的返回值
递归函数:
如果一个函数在内部调用自身本身,这个函数就是递归函数。
举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n
,用函数fact(n)
表示
1 def fact(n): 2 if n==1: 3 return 1 4 return n * fact(n - 1)
递归函数特性:
- 必须有一个明确的结束条件;
- 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
- 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。
- 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)