函数
1、 函数的概念
a.函数所解决的问题:
复杂度增大、组织结构不清晰、可读性差、代码冗余、可扩展性差
函数就是具备某一种功能的物件
实现准备工具的过程称为函数的定义
遇到特定的场景拿来就用称为函数的调用
b.函数的分类:
内置函数
自定义函数
2、函数的使用:
1 先定义
2 再调用
a.函数的定义语法:
def 函数名(arg1,arg2,arg3):
“注释”
函数体
return 返回值
注意:
函数名一般是动词
b. retrun的使用:
return 返回值没有类型限制
在函数内部可以有多个return,但只能执行一次,函数就结束调用,并且会把return后的值作为函数执行的结果返回
没有return:返回None,等同于return None
return 一个值:返回该值
return 多个值:返回多个值组成的一个元组
c.定义的三种形式:
无参:应用场景仅仅只是执行一些操作,比如与用户交互、打印等
有参:需要根据外部传进来的参数,才能执行相应的逻辑操作,比如统计长度,求最大值
空函数:设计代码结构
3、函数的调用:
函数调用的三种形式:
a.语句形式
b.表达式形式
c.当做另外一个函数的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def my_max(x,y):
if x > y:
return x
else :
return y
my_max( 1 , 2 ) #语句形式
res = my_max( 1 , 2 ) * 10 #表达式形式
# res1=my_max(1,2) #如果不使用第三种形式要写这两行 # res2=my_max(res1,3) res2 = my_max(my_max( 1 , 2 ), 3 ) #函数调用可以当做另外一个函数的参数
print (res2)
|
练习:
1
2
3
4
5
6
7
8
9
10
11
|
#定义阶段 def foo():
print ( 'from foo' )
bar()
# print(foo) def bar():
print ( 'from bar' )
#调用阶段 foo() |
注意:
函数在定义阶段只检测语法,不执行代码
4、函数参数
a.参数的形式
1 形参
2 实参
1
2
3
4
5
6
7
8
9
10
11
12
|
#形参:在定义函数时,括号内的参数成为形参 #特点:形参就是变量名 # def foo(x,y): #x=1,y=2 # print(x) # print(y) #实参:在调用函数时,括号内的参数成为实参 #特点:实参就是变量值 # foo(1,2) #在调用阶段实参(变量值)才会绑定形参(变量名) #调用结束后,解除绑定 |
b.参数的分类:
1 位置参数:按照从左到右的顺序依次定义的参数
位置形参:必须被传值,并且多一个不行,少一个也不行
位置实参:与形参按照位置一一对应
1
2
3
4
5
6
7
8
9
|
位置参数:按照从左到右的顺序依次定义的参数 位置形参:必须被传值,并且多一个不行,少一个也不行
位置实参:与形参按照位置一一对应
def foo(x,y):
print (x)
print (y)
foo( 'egon' , 1 , 2 )
|
2 关键字实参:指的是按照name=value的形式,指名道姓地给name传值
注意问题:
问题一: 语法规定位置实参必须在关键字实参的前面
问题二: 一定不要对同一个形参传多次值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
关键字实参:指的是按照name = value的形式,指名道姓地给name传值
def foo(name,age):
print (name)
print (age)
foo( 'egon' , 18 )
foo(age = 18 ,name = 'egon' )
关键字实参需要注意的问题是: def foo(name,age,sex):
print (name)
print (age)
print (sex)
foo( 'egon' , 18 , 'male' )
print ( '======>' )
foo(sex = 'male' ,age = 18 ,name = 'egon' )
foo( 'egon' ,sex = 'male' ,age = 18 )
问题一:语法规定位置实参必须在关键字实参的前面 foo( 'egon' ,sex = 'male' ,age = 18 )
问题二:一定不要对同一个形参传多次值 foo( 'egon' ,sex = 'male' ,age = 18 ,name = 'egon1' )
foo( 'male' ,age = 18 ,name = 'egon1' )
|
3 默认形参:在定义阶段,就已经为形参赋值,意味在调用阶段可以不用传值
默认参数需要注意的问题:
问题一:默认参数必须放在位置参数之后
问题二:默认参数只在定义阶段赋值一次,而且仅一次
问题三:默认参数的值应该定义成不可变类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
默认形参:在定义阶段,就已经为形参赋值,意味在调用阶段可以不用传值 def foo(x,y = 1111111 ):
print (x)
print (y)
foo( 1 , 'a' )
def register(name,age,sex = 'male' ):
print (name,age,sex)
register( 'asb' , 73 )
register( 'wsb' , 38 )
register( 'ysb' , 84 )
register( 'yaya' , 28 , 'female' )
默认参数需要注意的问题 问题一:默认参数必须放在位置参数之后 def foo(y = 1 ,x):
print (x,y)
问题二:默认参数只在定义阶段赋值一次,而且仅一次 x = 100
def foo(a,b = x):
print (a,b)
x = 111111111111111111111111111111
foo( 'egon' )
问题三:默认参数的值应该定义成不可变类型 |
4 可变长参数:指的是实参的个数不固定
形参必须要两种机制来分别处理实参:
按照位置定义的实参溢出的情况:*
跟按照关键字定义的实参溢出的情况:**
处理位置实参:*会把溢出的位置实参保存成元组
1
2
3
4
5
6
7
8
9
10
11
12
13
|
def foo(x,y, * args): #nums=(3,4,5,6,7)
print (x)
print (y)
print (args)
foo( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) #*
foo( 1 , 2 ) #*输出结果:
1 2 ( 3 , 4 , 5 , 6 , 7 )
1 2 () |
处理关键字实参:**会把溢出的关键字实参保存成字典
1
2
3
4
5
6
7
8
|
def foo(x,y, * * kwargs): #kwargs={'z':3,'b':2,'a':1}
print (x)
print (y)
print (kwargs)
foo( 1 , 2 ,z = 3 ,a = 1 ,b = 2 ) #**输出结果:
1 2 { 'z' : 3 , 'a' : 1 , 'b' : 2 }
|
*、**结合使用
1
2
3
4
|
def wrapper( * args, * * kwargs): #args=(1,2,3) kwargs={'a':1,'b':2}
print (args)
print (kwargs)
wrapper( 1 , 2 , 3 ,a = 1 ,b = 2 )
|
命名关键字参数:在*后面定义的形参称为命名关键字参数,必须是以关键字实参的形式传值
1
2
3
4
5
6
7
8
|
def foo(name,age, * args,sex = 'male' ,group):
print (name)
print (age)
print (args)
print (sex)
print (group)
foo( 'alex' , 18 , 19 , 20 , 300 ,group = 'group1' )
|
5、函数对象
函数是第一类的对象:指的是函数可以被当做数据传递
a.被赋值
b.可以当做参数传入
c.可以当做函数的返回
d.可以当做容器类型的元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
def foo():
print ( 'from foo' )
f = foo #把函数名赋值给变量
print (f)
f() #使用变量名可以调用函数
def wrapper(func):
# print(func)
func()
wrapper(foo) #把函数名foo当做参数传递给func
def wrapper(func): #把函数名foo当做参数传递给func,func当做return
return func #的返回值
res = wrapper(foo)
print (res)
cmd_dic = {
'func' :foo #把函数名以value的形式传入字典中
} print (cmd_dic)
cmd_dic[ 'func' ]()
|
函数练习:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
1 、写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批量修改操作
filename = input ( '请输入你要修改的文件名:' )
old = input ( '请输入你要修改的内容:' )
new = input ( '请输入新内容:' )
def modify(filename,old,new):
import os
with open (filename, 'r' ,encoding = 'utf-8' ) as read_f,\
open ( '.bak.swap' , 'w' ,encoding = 'utf-8' ) as write_f:
for line in read_f:
if old in line:
line = line.replace(old,new)
write_f.write(line)
os.remove(filename)
os.rename( '.bak.swap' ,filename)
modify(filename,old,new) 2 、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
def calculation( str ):
res = {
'nums' : 0 ,
'string' : 0 ,
'space' : 0 ,
'other' : 0
}
for s in str :
if s.isdigit():
res[ 'nums' ] + = 1
if s.isalpha():
res[ 'string' ] + = 1
if s.isspace():
res[ 'space' ] + = 1
else :
res[ 'other' ] + = 1
return res
str = input ( '请输入要判断的字符串:' )
res = calculation( str )
print (res)
3 、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于 5
def judge( object ):
if len ( object ) > 5 :
return object
object = input ( '请输入字符串、列表或元组:' )
judge( object )
4 、写函数,检查传入列表的长度,如果大于 2 ,那么仅保留前两个长度的内容,并将新内容返回给调用者
def check( str ):
if len ( str ) > 2 :
str = str [ 0 : 2 ]
return str
str = input ( '请输入元素:' )
print (check( str ))
5 、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者
def check_index(objects):
return objects[:: 2 ]
objects = input ( '请输入列表或元组:' )
print (check_index(objects))
6 、写函数,检查字典的每一个value的长度,如果大于 2 ,那么仅保留前两个长度的内容,并将新内容返回给调用者
dic = { 'k1' : 'v1v1' , 'k2' :[ 11 , 22 , 33 , 44 ]}
def check_dic(dic):
d = {}
for key,value in dic.items():
if len (value) > 2 :
d[key] = value[ 0 : 2 ]
return d
print (check_dic(dic))
本文转自lyndon博客51CTO博客,原文链接http://blog.51cto.com/lyndon/1948661如需转载请自行联系原作者 迟到的栋子 |