函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。 函数能提高应用的模块性,和代码的重复利用率。 有很多内置函数可以直接使用,也可以自定义函数。
函数的语法
参数可以没有,参数可以为任意多个。 return语句可以没有,没有时返回None。 函数文档用三引号,外部通过help(函数名)可以得到。 函数名不要使用关键字和系统函数,其它按照命名规则。
def function_name ( parameters[ 0 个或者多个] ) :
"""
函数文档 #可以通过help(函数名访问得到)
"""
函数体
return [ expression] ( 可有可无)
函数形参类型
写在函数定义时的参数称作“形参” – def 函数名(形参):。 函数调用时传入的参数称为“实参” – 函数名(实参)。
位置形参
在调用函数时,形参和实参位置及数量必须保持一致。 实参传参时,可以使用位置参数,关键字参数,可变参数传参。
位置形参语法
def 函数名( 形参1 ,形参2 , . . . )
- - -
位置形参举例
def bird_act ( name, act) :
print ( f" { name} can { act} ." )
bird_act( act= "fly" , name= "oriole" )
bird_act( "oriole" , "fly" )
result:
oriole can fly.
oriole can fly.
关键字形参
关键字形参语法
实际上是可变形参中*,之后的参数需要为关键字形参。
def 函数名( * ,关键字形参1 ,关键字形参2 , . . . )
- - -
def 函数名( * args,关键字形参1 ,关键字形参2 , . . . )
- - -
关键字形参举例
def bird_act ( * , name, act) :
print ( f" { name} can { act} ." )
bird_act( act= "fly" , name= "oriole" )
bird_act( "oriole" , "fly" )
result:
oriole can fly.
bird_act( ) takes 0 positional arguments but 2 were given
def bird_act ( * args, name, act) :
print ( f" { args} , { name} can { act} ." )
bird_act( 1 , 2 , 3 , act= "fly" , name= "oriole" )
bird_act( 1 , 2 , 3 , "oriole" , "fly" )
result:
( 1 , 2 , 3 ) , oriole can fly.
bird_act( ) missing 2 required keyword-
默认形参
形参和实参数目可以不一致,如果默认形参没有传递值,则用默认值。 定义时位置参数在前,默认参数要放最后。 默认参数不要使用可变类型 ,否则会出现默认参数变掉的情形。 如果前面有可变参数,则默认形参默认是不传递的。
默认形参语法
def 函数名( - - - , 默认形参1 = value1,默认形参2 = value2)
默认形参举例
def person ( name, age, * args, job= "剑客" ) :
print ( f" { name} , { age} , { job} , { args} " )
print ( * args)
person( '张三' , '18' , "越女剑" , "倚天剑" )
result:
张三, 18 , 剑客, ( '越女剑' , '倚天剑' )
越女剑 倚天剑
可变形参
*args:可变参数,可接收多个参数,会把多个位置参数值封装成元组的形式传入args。 **kwargs:可变参数,可接收多个参数,会把关键字参数值当成字典的形式传入kwargs。
可变形参举例
def person ( name, * args, ** kwargs) :
print ( "{} is {}, he likes {}" . format ( name, args, kwargs) )
print ( * args)
person( "Jack" , "cool" , "smart" , hobby1= "swimming" , hobby2= "reading" )
result:
Jack is ( 'cool' , 'smart' ) , he likes { 'hobby1' : 'swimming' , 'hobby2' : 'reading' }
cool smart
def person ( name, * args, ** kwargs) :
print ( "{} is {}, he likes {}" . format ( name, args, kwargs) )
print ( * args)
person( "Jack" , * [ "cool" , "smart" ] , ** { 'hobby1' : 'swimming' , 'hobby2' : 'reading' } )
result:
Jack is ( 'cool' , 'smart' ) , he likes { 'hobby1' : 'swimming' , 'hobby2' : 'reading' }
cool smart
函数调用实参传参
位置传参
关键字传参
实参根据形参的名字对应。 可以不按照形参的先后顺序。
序列传参
字典关键字传参
实参用**将字典拆解后与形参的名字进行对应。 可以配合形参的默认参数。
def person ( name, age, * args, gender= "Male" , ** kwagrs) :
print ( "{},{},{},{},{}" . format ( name, age, args, kwagrs, gender) )
person( "Lucy" , 18 , * [ "屠龙刀" , "倚天剑" ] , gender= "Female" ,
** { "kungfu1" : "HamaGong" , "kungfu2" : "FeiheQuan" } )
result:
Lucy, 18 , ( '屠龙刀' , '倚天剑' ) , { 'kungfu1' : 'HamaGong' , 'kungfu2' : 'FeiheQuan' } , Female
实参传参注意事项:
当使用了关键字传参后,后面的其它参数不能再使用位置传参。 关键字传参,必须放置于*args之后,**kwagrs之前(否则默认参数)。 *args,**args均最多使用1个。
函数调用传参内存
参数为可变类型
传递的是对象的引用,即实参的地址,形参和实参指向相同的地址。 当形参改变时,实参对应的内容也发生改变。
参数为不可变类型
传递的仍是对象的引用,但是不可变对象改变时,会重新分配内存,所以形参会指向新的地址,实参所指地址内的内容不会受到任何影响。
x,y和a,b指向相同的地址,但是因为地址里是不可变对象,所以当改变时,会重新开辟内存,x,y又重新指向了新的地址,所以x,y的改变不会影响到a,b。 传递不可变对象,如果不可变对象的子对象是可变的,则在函数内修改这个可变对象,实参对应的这个子对象也发生修改。
函数返回值
用 return 语句指定函数的返回值,该返回值可以是任意类型。 一个函数可以存在多条return语句,但只有一条可以被执行,如果没有一条return语句被执行,同样会隐式调用return None作为返回值。 当无return语句时,默认返回None。 return语句的作用是返回值,结束函数。 该返回值可以为其它地方所使用。 如果返回一个值,那么是返回的一个值,该值可以是任意类型。如果返回多个值,那么返回的是一个元组。
def get_data ( ) :
a, b, c, d = 1 , 2 , 3 , 4
return a, b, c, d
print ( '返回值的类型:' , type ( get_data( ) ) )
print ( '返回值:' , get_data( ) )
result:
返回值的类型: < class 'tuple' >
返回值: ( 1 , 2 , 3 , 4 )
函数可以作为另一个函数的返回值
def fx ( ) :
return max
fn = fx( )
print ( fn, max )
print ( fn( [ 1 , 3 , 5 , 7 ] ) )
result:
< built- in function max > < built- in function max >
7