函数初始
一、什么是函数
现在有这样一个情况:Python中的len()方法不让用了,你怎么办?
来测试一下 :'hello world' 的长度:
s1 = 'hello world'
length = 0
for i in s1:
length += 1
print(length)
11
OK,完事儿了,非常完美。但是主管又提出一个需求,要求计算两外一个字符串的长度:‘hello china’,于是你的代码就变成这样了:
s1 = 'hello world'
length = 0
for i in s1:
length += 1
print(length)
s2 = 'hello china'
length = 0
for i in s2:
length += 1
print(length)
11
11
这样确实可以实现len()方法的效果,但是总感觉不是那么完美?为什么呢?
首选,之前只要我们执行len()方法就可以直接拿到一个字符串的长度了,现在为了实现相同的功能我们把相同的代码写了好多遍————代码冗余
其次,之前我们只写两句话读起来也简单,一看就知道这两句代码是在计算长度,但是刚刚的代码却不是那么容易读懂—————可读性差
所以,我们就想能不能用一段代码,来实现相同的功能,比如:我们写一个len()方法叫做my_len()方法,可以代替len()的方法,既解决了代码冗余,又让其可读性好,用什么方法?这就引出了我们今天讲的----函数
函数是组织好的,可重复使用的,用来实现单一或 相关联功能的代码段
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如:print(),len()等。但你也可以自己创建函数,这就叫做用户自定义函数
二、函数的定义与调用
#函数定义
def mylen():
#计算str的长度
str = "hello world"
length = 0
for i in str:
length += 1
print(length)
#函数调用
mylen()
11
上面我们写了一个函数,并且成功的调用了它
定义:def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"
def 是固定的,不能变,他就是定义函数的关键字
空格 为了将def关键字和函数名分开,必须空(四声),当然你可以空2格、3格或者你想空多少都行,但正常人还是空1格
函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并能表达函数功能
括号:是必须加的
注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性
调用:就是 函数名() 要记得加上括号
三、函数的返回值
调用len()方法时,得到的结果会赋值给一个变量,然后的到结果:
str_len = len('hello world')
print(str_len)
11
但是我们写的mylen()函数,并不会得到这样的结果,如何让他们和len()函数一样,有返回值呢?
那需要在函数的最后加上一个return,return后面写你需要的放回 值就可以了
# #函数定义
def mylen():
#计算str的长度
str = "hello world"
length = 0
for i in str:
length += 1
return length
#函数调用
mylen()
str_len = mylen()
print('字符串长度:%s' % str_len)
字符串长度:11
return是一个关键字,表示的意思是"返回值,"在pycharm里,你会看到return的颜色变蓝了
返回值有几种情况:分别是没有返回值、返回一个值、返回多个值
没有返回值:不写return,会默认返回值为一个None
#函数定义
def mylen():
#计算str的长度
str = "hello world"
length = 0
for i in str:
length += 1
print(length)
#函数调用
str_len = mylen()
print('字符串长度:%s' % str_len)
11
字符串长度:None
只写return,后面什么都不写,也会返回一个None,这里的用法是函数内部一旦遇到return,就结束整个函数
def ret_mode():
print("start")
return
print("end")
ret = ret_mode()
print(ret)
start
None
return None:和上面的情况一样,我们一般不这么写
返回一个值:只需要在return后面加上要返回的内容就可以了
#函数定义
def mylen():
#计算str的长度
str = "hello world"
length = 0
for i in str:
length += 1
return length
#函数调用
str_len = mylen()
print('字符串长度:%s' % str_len)
字符串长度:11
返回多个值:可以返回任意多个、任意数据类型的值
def ret_demo1():
#返回多个、同一类型的数据
return 1,2,3,4
def ret_mode2():
# 返回多个、任意类型的数据
return 1, ['a','b','c'],3,4,'abc'
ret1 = ret_demo1()
print(ret1)
ret2 = ret_mode2()
print(ret2)
(1, 2, 3, 4)
(1, ['a', 'b', 'c'], 3, 4, 'abc')
返回多个值会被组织成元组被返回,也可以用多个值来接收
def ret_demo1():
#返回多个、同一类型的数据
return 1,2,3,4
def ret_mode2():
# 返回多个、任意类型的数据
return 1, ['a','b','c'],3,4,'abc'
#返回多个值,用一个变量接收
ret1 = ret_demo1()
print(ret1)
print()
#返回多个值,用多个变量接收,返回几个值,就用几个变量接收
a,b,c,d,e = ret_mode2()
print(a)
print(b)
print(c)
print(d)
print(e)
(1, 2, 3, 4)
1
['a', 'b', 'c']
3
4
abc
四、函数的参数
现在,我们已经把函数返回值的相关事情弄明白了,我们已经完成了一个可以返回字符串长度的函数mylen()。但是现在这个函数还是不是很完美,之前我们使用len()函数的时候,是length = len('hello world'),这样我们可以想计算谁就计算谁的长度。但是现在我们写的这个函数,只能计算一个'hello world'这个字符串的长度,换一个字符串好像就不行了,该怎么办呢?
#函数定义
def mylen(str):
#计算字符串的长度
length = 0
for i in str:
length += 1
return length
#函数的调用
str_len = mylen('hello world')
print('字符串的长度:%s' % str_len)
字符串的长度:11
我们告诉mylen()函数要计算的字符串是谁,这个过程叫做传到参数,简称:传参,我们调用函数时传递的 'hello world' 和定义函数时的 str 就参数, 'hello world' 是实参,str是形参
实参、形参:
'hello world' 是调用函数时实际传递的参数,简称:实参
定义函数 mylen(str) 的 str,只是一个变量的名字,被称为形式参数,在定义函数的时候它表示的只是一个形式,表示函数这里有一个参数,简称:形参
传递多个参数:参数可以传递多个,多个参数之间用逗号分割
def mymax(x,y):
the_max = x if x > y else y
return the_max
max = mymax(10,20)
print(max)
20
位置参数:从实参角度讨论
1、按照位置传值
def mymax(x,y):
#此时 x = 10, y = 20
the_max = x if x > y else y
return the_max
max = mymax(10,20)
print(max)
2、按照关键字传值
def mymax(x,y):
#此时 x = 20, y = 10
the_max = x if x > y else y
return the_max
max = mymax(y = 10,x = 20)
print(max)
20
3、位置、关键字形式混合使用
def mymax(x,y):
#此时 x = 20, y = 10
the_max = x if x > y else y
return the_max
max = mymax(10,y = 20)
print(max)
正确的用法:
1、位置参数必须在形式参数的前面
2、一个形参只能赋值一次
位置参数:从形参的角度来讨论
1、位置参数必须传值
def mymax(x,y):
the_max = x if x > y else y
return the_max
#调用mymax不传递参数
max = mymax()
print(max)
TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'
默认参数:将变化比较小的参数,设置为默认参数
1、默认参数的定义
def stu_info(name,sex = '男'):
"""打印学生信息函数,由于班级中大部分学生是男生,所以设置默认参数:sex的默认值为 '男'"""
print(name,sex)
stu_info('小明')
stu_info('小红','女')
小明 男
小红 女
2、参数陷阱:默认参数是一个可变数据类型
def default_param(name,list=[]):
list.append(name)
print(list)
default_param('alex')
default_param('eqon')
['alex']
['alex', 'eqon']
动态参数
动态参数,也叫不定长传参,当需要传给函数的参数很多,个数不定的情况下,就需要使用 *args,**kwargs 来接收,
args是元组形式,接收除去键值对以外的所有参数,kwargs接收的只是键值对的参数,并保存在字典中
def trans_param(*args,**kwargs):
print(type(args))
print(args)
print(type(kwargs))
print(kwargs)
trans_param('jinxin',12,[1,2,3,4],[2,3],(1,4,7),{'a':'123','c':456},country = 'china')
<class 'tuple'>
('jinxin', 12, [1, 2, 3, 4], [2, 3], (1, 4, 7), {'a': '123', 'c': 456})
<class 'dict'>
{'country': 'china'}