函数(上)
一、函数的定义:
1、函数的定义规则:
自定义函数时,需要满足一些规则,否则编译器不会识别。
(1)函数代码块以def关键词开头,后接函数标识符名和圆括号()。
(2)任何传入实参和形参必须放在圆括号中。圆括号中写的是形参。
(3)函数的第一行语句可以选择性地使用文档字符串—-用于存放函数说明。
(4)函数内容以冒号起始,并且函数体要有缩进。
(5)return[expression]结束函数,选择性地返回一个值给调用者。不带表达式
的return相当于返回None。
2、语法:
def functionname( parameters ):
"函数_文档字符串"
function_suite
return[expression]
默认情况下,参数值和参数名称是按函数声明中定义的的顺序匹配起来的。
3、python定义函数,每个函数需要有return()返回值才算是完整的函数,如果没有返回值,会是一个None值
二、函数的参数
1、无参函数:
def sayHello(): print 'Hello World!' sayHello()
2、有参函数
python中调用函数时,使用的形参包括下列几种:
- 必备参数
- 命名参数
- 缺省参数
- 不定长参数
2.1、有参函数——必备参数:
2.1.1、必备参数—传不可变参数(字符串,数字)
说明:如果函数收到的是一个不可变对象(比如数字、字符或者元组)的参数,这个时候就是通过“传值”来传递对象,此时如果想改变原变量的值,可以将这些变量申明为全局变量
1、传递参数如果跟函数参数个数不同就会报错。
def info(name, age, tel) : print "name:" + name + ", age:" + str(age) +", tel:" + tel info('jack', 20,'13567867878') info('jack', 20,') #传递参数个数不同,会报错
2、、局部变量和全局变量:
局部变量:有入参,把值传给函数
示例1:
def changeNum(num): num+=1 print u'自定义函数中的num=',num num=10 changeNum(num) print u'函数调用后的num=',num 运行结果: 自定义函数中的num= 11 函数调用后的num= 10
全局变量:没有入参,可以改变函数的值。如果在函数内改动全局变量,不传参和加上全局变量说明global
示例2:
def changeNum(): global num num+=1 print u'自定义函数中的num=',num num=10 changeNum() print u'函数调用后的num=',num
为避免全局变量和局部变量混淆出错,建议:
a、函数内变量名称和全局变量名称不要重名
b、使用全局变量时,需要使用global在函数内声明全局变量
2.1.2、必备参数—传可变对象(列表或字典)
1、如果函数收到的是一个可变对象(比如字典或者列表)的参数,这个时候就是通过传“引用”来传递的参数(其实这种归根结底传的也是值,只不过是指向内存空间地址的值)
示例:
def chaneList(list1): list1.append('newstr') print u'函数中的list1:',list1 list1=[1,2,3] print u'调用函数前的list1:',list1 chaneList(list1) print u'调用函数后的list1:',list1 运行结果: 调用函数前的list1: [1, 2, 3] 函数中的list1: [1, 2, 3, 'newstr'] 调用函数后的list1: [1, 2, 3, 'newstr']
2、传可变对象是默认参数,会改变对象的值
示例:
def add_end(L=[]): L.append('END') return L print add_end([1,2,3]) #传参非空,调用正常 print add_end(['x','y','z']) #传参非空,调用正常 print add_end() #第一次传默认参数,调用正常 print add_end() #第二次传默认参数,已记住上一次的list值,调用不正常 print add_end() #第三次传默认参数,已记住上一次的list值,调用不正常 运行结果: [1, 2, 3, 'END'] ['x', 'y', 'z', 'END'] ['END'] ['END', 'END'] ['END', 'END', 'END']
说明:
a、Python函数在定义的时候,默认参数L的值就被计算出来了,即[]
b、因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
c、注意:定义默认参数要牢记一点:默认参数必须指向不变对象!
3、函数应该检查传参的数据类型,避免乱调用:
def my_abs(x): if not isinstance(x,(int,float)): raise TypeError('bad operand type') if x>=0: return x else: return -x print my_abs(-1) print my_abs('x')
2.2、有参函数——命名参数
注意:传参时命名参数必须在非命名参数后面,否则就会报SyntaxError:non-keyword arg after keyword arg的错误.
示例:
def sum(a,b,c): sum=a*100+b*10+c return sum print 'sum=',sum(3,b=2,c=5) 运行结果: sum= 325
2.3、有参函数——缺省参数
1、注意:默认值必须要放到没有默认值参数的最后面,否则会报错。这是因为赋给形参的值是根据位置而赋值的
示例:
def say(message,times=1): return message*times print say('hello world!') print say(u'加油!',3) 运行结果: hello world! 加油!加油!加油!
2、指定多个默认值,通过命名方式来赋值,也称为关键参数赋值(使用名字进行赋值,而不是位置进行赋值)
示例:
def func(x,y=4,z=6): print 'x is',x print 'y is',y print 'z is',z func(3,5) print "-"*15 func(25,z=8) print "-"*15 func(z=20,x=100) 运行结果: x is 3 y is 5 z is 6 --------------- x is 25 y is 4 z is 8 --------------- x is 100 y is 4 z is 20
2.4、有参函数——不定长参数(使用元组或字典作为参数)
1、不定长参数—使用元组作为参数
示例:函数传入元组参数,计算出传参的总和。
def sum(a,*b): # *表示传入值作为元组传入 sum=a for i in b: # print i #打印元组b中的所有值 sum+=i return sum print 'sum=',sum(1,2,3,4,5) #传入多个值时,第一个值作为a的值,后面的所有值为b的值,为一个元组(2,3,4,5) 运行结果: sum= 15
2、不定长参数—使用字典作为参数
示例:打印出传入字典
def sum(**kw): # **表示传入值作为字典传入 for k,v in kw.items(): print k,v sum(a=1,b=2,c=4,d=6) 运行结果: a 1 c 4 b 2 d 6
3、不定长参数—同时使用元组和字典作为参数(*和**作为函数参数)
示例:
def printInfo(a,b=2,*tup,**dic): print a print b print tup print dic printInfo(3,4,5,6,2,x=1,y=2) 运行结果: 3 4 (5, 6, 2) {'y': 2, 'x': 1}
说明:
按照参数赋值顺序,a=2,c=3,4和5存在元组tup中,x=1, y=2存在字典dic中。
由此可以看出,传参时元组和字典传参的区别:
元组就跟传普通参数一样,而字典中的元素是由键值对组成,所以传参时就需要传键值表达式。