函数是一段可以重复使用的代码,通过传递的参数返回不同的结果,函数能够提高应用的模块性和代码的重复利用率。
博文大纲:
一、函数
二、变量的作用域
三、内建函数
四、特殊函数——lambda函数
Python中的函数都是语句和表达式的集合。函数的用法并没有限制,使用方法就像Python中其他值一样,对于重复使用的代码,需要编写为自定义函数以便于重复使用。
在CentOS 7系统(默认是Python 2.7.5)中实现!
函数可以分为:
- 无参函数;
- 有参函数;
(1)自定义无参函数,语法格式如下:
def 函数名称():
代码块
return 表达式
以关键字def开始,后面跟函数名和小括号,以冒号开头并缩进,最后使用return退出函数,有表达式则传递返回值,没有则返回None。函数是以字母、数字和下划线组成的字符串,但是不能以数字开头。
无参函数的调用语法如下:
[变量 = ] 函数名称()
使用赋值运算符“=”可以获得函数的返回值,使用函数是必须先定义再调用,否则程序会出现错误。
实例:
[root@localhost ~]# vim 1.py
#coding:utf-8
def add(): //定义函数
op1=10
op2=20
rt=op1+op2
print op1,'+',op2,'=',rt
return
add() //调用函数
[root@localhost ~]# python 1.py //输出结果
10 + 20 = 30
上述代码中,定义了无参函数add(),输出了10+20的值,return语句并没有返回值,直接使用函数名add()进行了调用。
将上述代码稍作修改,用return语句返回结果值,代码如下:
[root@localhost ~]# vim 1.py
#coding:utf-8
def add():
op1=10
op2=20
rt=op1+op2
return rt
i=add() //将函数的返回值赋值给i
print i
[root@localhost ~]# python 1.py //输出结果
30
函数add()使用return语句返回相加的结果值,变量i接收函数add()返回的值。Python在处理返回值时,如果没有return语句,会默认返回None,程序并不会报错。
九九乘法表实例:
[root@localhost ~]# vim 1.py
#coding:utf-8
def a():
for i in range(1,10):
for j in range(1,i+1):
print i, "*", j, "=" ,i*j,
print "\t"
a()
[root@localhost ~]# python 1.py
1 * 1 = 1
2 * 1 = 2 2 * 2 = 4
3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16
5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25
6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36
7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49
8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64
9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
(2)使用函数时经常会犯一些错误,比如:
(3)编写一个用户登录页面的脚本,如下:
[root@localhost ~]# vim 1.py
#coding:utf-8
kgc={}
def newuser(): //定义创建新用户的无参函数
prompt1 = 'login desired:'
while True:
name = raw_input(prompt1)
if (kgc.has_key(name)): //has_key:用于判断name键是否存在kgc字典中
prompt1 = '--name taken,try another:'
continue
else:
break
pwd = raw_input('password:')
kgc[name]=pwd
def olduser(): //定义已有账号的无参函数
name = raw_input('login:')
pwd = raw_input('password:')
password = kgc.get(name) //获取name在kgc字典中的值
if password == pwd:
print "ok"
else:
print "no"
def showmenu(): //定义列表菜单,调用上两个无参函数
prompt='''
(N)ew User Login
(E)ntering User Login
(Q)uit
Enter choice:'''
while True:
choice = raw_input(prompt).strip()[0].lower()
//strip()表示去除字符串钱的多余字符,()表示空格
//[0]表示字符串的第一个字符
//lower()将字符变成小写
print '\n--You picked:[%s]' %choice
if choice not in 'neq':
print '--invalid option,try again--'
else:
if choice=='n':
newuser()
elif choice=='e':
olduser()
else:
print 'quit'
break
if __name__=='__main__': //定义程序入口
showmenu()
[root@localhost ~]# python 1.py //执行脚本
(N)ew User Login
(E)ntering User Login
(Q)uit
Enter choice:n //n表示新建用户
--You picked:[n]
login desired:lzj
password:123
(N)ew User Login
(E)ntering User Login
(Q)uit
Enter choice:e //表示已有账号登录
--You picked:[e]
login:lzj
password:123
ok //登录成功,显示ok
(N)ew User Login
(E)ntering User Login
(Q)uit
Enter choice:q //q表示退出脚本
--You picked:[q]
quit
(1)带参函数的语法格式:
def 函数名称(形式参数列表):
代码块
return [表达式]
通过语法,可以看出带参函数与无参函数的区别就是在函数名称后的小括号中有形式参数列表,参数列表实际上只是占位符,用于体现参数的个数,每个参数都没有提供具体的数值。
带参函数的调用语法如下:
[变量 = ] 函数名称( 参数列表)
调用时只需要在每个参数传递对应的实际数值,就可以完成函数的调用。
实例:
[root@localhost ~]# vim 1.py
#coding:utf-8
def add(x,y):
return x+y
print add(1,2)
[root@localhost ~]# python 1.py
3
上述代码中定义了函数add(),它有两个形式参数x和y,在函数的语句块中可以使用x和y,和使用变量是类似的。通过函数名add()和实际的参数值1和2进行调用,所以返回值是3.
(2)当调用函数时,传递的实际参数值是根据位置来跟函数定义的参数表匹配的,如下:
[root@localhost ~]# vim 1.py
#coding:utf-8
def add(x,y):
print x,y
add(1,2)
add(10,20)
[root@localhost ~]# python 1.py
1 2
10 20
在函数add(x,y)中,输出x,y值,x在前,y在后。调用add(1,2)时,x的值是1,y的值是2;当调用add(10,20)时,x的值是10,y的值是20,所以在最后的输出结果是不同的。
(3)当程序比较繁琐时,参数的顺序是很难记住的,可以使用关键字参数。关键字参数实在调用函数时,明确指定参数值付给那个形参,语法格式如下:
函数名称(形参1=实参1,形参2=实参2……)
实例:
[root@localhost ~]# vim 1.py
#coding:utf-8
def add(x,y):
print x,y
add(x=1,y=2)
add(y=10,x=20)
[root@localhost ~]# python 1.py
1 2
20 10
在调用的过程中,明确指定了实参是形参的对应关系,所以在输出的时候,就不会因为位置的原因,而错乱顺序。
(4)调用普通参数函数时,传入的参数个数必须和声明的参数个数一致。但关键字参数有一个特殊的作用,可以在定义函数时设置关键字参数的默认值,此时传入函数的参数就可以和声明的参数个数不一致了。
实例:
[root@localhost ~]# vim 1.py
#coding:utf-8
def add(x,y=100):
print x,y
add(x=100)
add(100,200)
[root@localhost ~]# python 1.py
100 100
100 200
定义时参数y的默认值是6,调用时,可以不传递y的值,只传递x的值即可,直接传值或使用参数名并赋值都可以;如果定义了y的值,则y的默认值将不生效。
注意:定义关键字参数默认值时需要注意,位置参数必须出现在默认参数之前,比如以下的函数定义时错误的:
#coding:utf-8
def add(x=1,y):
print x,y
add(x=100)
add(100,200)
(5)编写一个计算器程序
需求如下:
#coding:utf-8
def operator(op1,op2,opfu):
if opfu not in '+-*/':
return -1
if opfu =='+':
result = op1+op2
elif opfu =='-':
result = op1-op2
elif opfu =='*':
result = op1*op2
elif opfu =='/':
if op2 == 0:
print '错误,除数不能为0!/n'
result = None
else:
result = op1/op2
return result
def convert(op):
flag = True
for ch in op:
if ch not in '1234567890':
flag = False
break
if flag == True:
return int(op)
else:
return None
if __name__=='__main__':
str1 = '请输入第一个数:\n'
strfu = '请输入一个算数运算符:\n'
str2 = '请输入第二个数:\n'
while True:
print '需要退出程序,请输入字母q'
opp1 = raw_input(str1)
ch = opp1.strip()[0].lower()
if ch == 'q':
break
op1 = convert(opp1)
if op1 ==None:
print '输入错误,请输入整数!\n'
continue
while True:
opfu = raw_input(strfu)
if opfu in '+-*/':
break
else:
print '运算符输入错误'
continue
while True:
op2 = convert(raw_input(str2))
if op2 == None:
print "输入错误,请输入整数!\n"
continue
else:
break
result = operator(op1,op2,opfu)
if result <> None:
print "计算%d %s %d = %d \n" %(op1,opfu,op2,result)
print '程序退出了'
#执行结果如下:
需要退出程序,请输入字母q
请输入第一个数:
10
请输入一个算数运算符:
*
请输入第二个数:
2
计算10 * 2 = 20
需要退出程序,请输入字母q
请输入第一个数:
q
程序退出了
现在对上述代码进行分段解释:
第一段代码:
def operator(op1,op2,opfu):
if opfu not in '+-*/':
return -1
if opfu =='+':
result = op1+op2
elif opfu =='-':
result = op1-op2
elif opfu =='*':
result = op1*op2
elif opfu =='/':
if op2 == 0:
print '错误,除数不能为0!/n'
result = None
else:
result = op1/op2
return result
在上面代码中,位置1处定义了函数operator(op1,op2,opfu),参数op1表示运算符前面的数值,op2表示运算符后面的数值,opfu表示运算符,然后先判断opfu是不是“+-*/”中的其中一个,如果不是,返回值是-1,表示程序出错。在接下来就是判断是哪个运算符号,就进行哪种运算处理。但是在判断除法运算符时,需要加一个条件,就是除数不能是0,因为除数是0在数学上是没有意义的,最后只要把运算的结果返回即可。
第二段代码:
def convert(op):
flag = True
for ch in op:
if ch not in '1234567890':
flag = False
break
if flag == True:
return int(op)
else:
return None
在上面的代码中,首先定义了一个布尔型变量flag,用于判断数值的有效性,在for循环语句中,op是传进来的字符串,使用for循环判断它的每一个字符是不是在“1234567890”中,如果有一个不再,说明这个字符串不能转换为数值,flag的值为False,退出循环,否则flag的值不变,还是True,说明字符串可以转换为数值型。然后接下来做了相应的判断,把字符串op转换为了整型,使用的是int()函数。最后是如果不能转换为整型,返回的是None。
第三段代码:
if __name__=='__main__':
#以下是定义三个字符串的提示文字
str1 = '请输入第一个数:\n'
strfu = '请输入一个算数运算符:\n'
str2 = '请输入第二个数:\n'
#下面是主体代码的无限循环操作,可以用来进行多次计算
while True:
print '需要退出程序,请输入字母q'
#以下是判断当键盘输入q时,就退出程序
opp1 = raw_input(str1)
ch = opp1.strip()[0].lower()
if ch == 'q':
break
#对输入的第一个字符串进行数值转换操作,convert()返回是None,说明不能转换,使用continue进入到下一次循环重新输入。
op1 = convert(opp1)
if op1 ==None:
print '输入错误,请输入整数!\n'
continue
#等待输入运算符,如果是“+-*/”中的一个,使用break结束循环,否则执行continue,重新输入
while True:
opfu = raw_input(strfu)
if opfu in '+-*/':
break
else:
print '运算符输入错误'
continue
#下面是输入第二个数值,同样需要做转换操作,如果不能转换就需要重新输入
while True:
op2 = convert(raw_input(str2))
if op2 == None:
print "输入错误,请输入整数!\n"
continue
else:
break
#下面就是调用函数operator进行运算,result不等于None就说明运算是正常的,显示出运算结果
result = operator(op1,op2,opfu)
if result <> None:
print "计算%d %s %d = %d \n" %(op1,opfu,op2,result)
print '程序退出了'
作用域是指变量在程序中的应用范围,而变量声明的位置决定它的作用域,Python按作用域区分有局部变量和全局变量。
全局变量是指在一个模块中最高级别的变量有全局作用域,除非被删除,否则存活到程序运行结束,所有函数都能访问全局变量。
局部变量是指定义在函数内的变量有局部作用域,依赖于定义变量的函数现阶段是否处于活动状态,调用函数时,局部变量产生,暂时存在,一旦函数执行完成,局部变量就不存在了。
局部变量的作用域仅限于定义它的函数,全局变量的作用域在整个模块内部都是可见的。在同一个函数中,不允许有同名的局部变量,在不同函数中,可以有同名的局部变量。在同一个程序中,全局变量和局部变量同名时,局部变量具有更高的优先级。
示例:
#代码如下:
def addage(age):
age += 1
print 'addage():_age=%d age=%d' %(_age,age)
return age
_age = input('请输入年龄:\n')
rt = addage(_age)
print 'main():_age = %d'%_age
print 'main(): rt=%d' %rt
#执行结果如下:
请输入年龄:
10 #输入一个“10”
addage():_age=10 age=11
main():_age = 10
main(): rt=11
在上面的代码中,函数addage(age)中定义了局部变量age,在全局范围定义了全局变量_age。_age的值是由我们键盘输入的,它在全局都生效,所以在addage(age)函数中也可以对它进行引用。当键盘输入是10时,_age的值是10,调用“rt=addage(_age)”,就是把全局变量_age的值10传给了函数,此时addage(age)的局部变量age的值也是10,执行age += 1后,age值成为了11,而全局变量_age的值不发生变化,打印输出“_age=10 age=11”,函数的返回值age的值是11,由rt接收,所以打印“_age=10,rt=11”
通过上面的代码示例,可以看出Python采用的是值传递的方式,但实际上并不是这样。Python采用的是值传递和引用传递相结合的方式,当传递可变对象时(如字典或者列表),相当于传引用,而不可变对象(如数字、字符或元组)就是值传递。上面传递的是字符串,所以是值传递的方式。
在Python中尽量不使用全局变量,因为程序中可以自由的访问全局变量,其他人并不知道哪个变量是全局变量,非常容易出现引用错误,这种错误也很难发现和更正的。
局部变量只有在局部中才能使用,其他范围是访问不到的,如上面的代码汇总age是局部变量,在全局范围就引用不到,比如在上面程序中加上下面这行代码,就会报错。
#在上面代码末尾加上下面这段代码:
# ....................省略部分内容
print 'main():age = %d'%age
#执行结果如下:
请输入年龄:
10
addage():_age=10 age=11
main():_age = 10
main(): rt=11
Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/aa.py", line 9, in <module>
print 'main():age = %d'%age
NameError: name 'age' is not defined #提示age没有定义
错误显示age没有定义,说明在全局范围age是访问不到的,这个问题可以使用global关键字解决,global的作用是声明变量为全局变量,即使变量定义在函数内部,加上global后,也可以在全局范围访问,修改后的代码如下:
def addage(num):
global age
age = num+1
print 'addage():_age=%d age=%d' %(_age,age)
return age
_age = input('请输入年龄:\n')
rt = addage(_age)
print 'main():_age = %d'%_age
print 'main(): rt=%d' %rt
print 'main():age = %d'%age
上面代码中做了一些调整,主要使用了global定义age,最后在全局引用age时,可以正常使用。
在函数中,使用global语句声明的全局变量名不能与其中的局部变量重名,而且尽量要避免在函数中使用global定义全局变量,减少程序的不可预知性。
Python除了本身的语法结构,还提供了常用的内建函数,内建函数是我们经常使用到的方法,可增加程序编写的效率,如float()函数就是内建函数。内建函数是自动加载的,Python的解释器可以识别,它不需要导入模块,不必做任何操作,不需要引用就可以调用。
1、abs()函数能够返回一个数字的绝对值,即整数,如下:
>>> abs(10)
10
>>> abs(-10)
10
>>> bb = -3
>>> abs(bb)
3
2、bool()函数返回值是TRUE或FALSE,它是布尔值的简写,可以用来判断字符是否为空,如下:
>>> bool() #无参数时返回False
False
>>> bool(0)
False
>>> bool(-3)
True
>>> bool(None)
False
>>> bool('xyz')
True
>>> bool('11,22')
True
3、float()函数用于转换数据为float(浮点)类型,字符串和数字都可以转换为float类型,如果不能转换,就会报错,如下:
>>> float(25)
25.0
>>> float(3)
3.0
>>> float(99.589456)
99.589456
>>> float('99.589456')
99.589456
4、int()函数可以将数据转换为整数,如下:
>>> int(199.99) #浮点数
199
>>> int('100') #字符串
100
>>> int('99.99') #字符串,字符串中只能是整数格式,如果是浮点型就会报错
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
int('99.99')
ValueError: invalid literal for int() with base 10: '99.99'
5、range()函数可以生成一个列表,如下:
>>> range(0,5)
[0, 1, 2, 3, 4]
>>> range(0,30,3) #第三位的数字代表步长,是可选参数
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
>>> range(30,0,-3)
[30, 27, 24, 21, 18, 15, 12, 9, 6, 3]
>>> for i in range(0,5):
print i
0
1
2
3
4
6、sum()函数可以对列表中元素求和,如下:
>>> num = range(0,500,50) #定义一个元组
>>> num #查看元组中的值
[0, 50, 100, 150, 200, 250, 300, 350, 400, 450]
>>> print (sum(num)) #对元组中的值进行求和操作
2250
7、max()函数可以返回列表、元组或字符串中最大的元素,如下:
>>> num = [6,2,12,7,65]
>>> max(num)
65
>>> str = 'a,d,g,c,D,U,A,N,G'
>>> max(str)
'g'
>>> max(1000,650,98,2689)
2689
8、min()函数返回列表、元组或字符串中值最小的元素,和max()正好相反,如下:
>>> min(10,9,7)
7
9、dir()函数可以返回关于任何值的相关信息,可以用于任何对象,包括字符串、数字、函数、模块、对象和类。相当于帮助手册。如下:
>>> dir() #无参数时,返回当前范围内的变量
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '_age', 'addage', 'age', 'bb', 'i', 'num', 'rt', 'str']
>>> dir(rt) #带参时,返回的是参数的属性、方法列表
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
10、eval()函数是可以计算表达式的值。如下:
>>> eval('100*9')
900
>>> eval(raw_input("请输入表达式:"))
请输入表达式:8+9*2-3
23
11、len()函数返回一个对象的长度,如下:
>>> len('lvjianzhao') #字符串
10
>>> language = ['python','java','c#','vb'] #列表
>>> len(language)
4
>>> person = {'zhangsan':'123','lisi':'234','wangwu':'345'} #定义一个字典
>>> len(person)
3
lambda函数的作用是创建匿名函数,是一种声明函数的特殊方式。
lambda函数的语法格式如下:
lambda params:expr
其中params相当于函数接受的参数列表,expr是函数返回值的表达式。
示例:
#代码如下
def sum1(x,y):
return x+y
sum2 = lambda x,y:x+y
print sum1(1,2)
print sum2(1,2)
#执行结果如下
3
3
实现的是相同的功能,但lambda函数更加简洁,只用一条语句实现,所以lambda也称为lambda表达式,使用lambda只能是表达式,不能包含if、for等条件循环语句,对于不需要复用、简单的匿名函数,使用lambda能起到很好的效果。
———————— 本文至此结束,感谢阅读 ————————
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。