文章目录
一、函数的理念和作用
对于大型的项目, 比较长的代码, 即使是代码的编写者也不可能对内部的每个逻辑记得很清楚.
这个时候很有可能读不懂代码到底都在写一些什么东西了.
但是对于一个封装好的函数, 我们只需要知道函数需要传入的参数, 以及函数输出的结果就可以了, 并不需要了解内不是如何实现这一功能的.就是把函数当成一个黑匣子来看待.
这样就大大简化了程序开发的难度, 所以这也是使用函数的一个很便捷的地方.
二、函数定义和调用
定义函数的格式如下:
def 函数名(函数参数1,函数参数2):
函数运行代码
例:
定义一个自我介绍函数:
def 自我介绍(name,number):
print('你好我叫{}'.format(name))
print("我的手机号是{}".format(number))
当我们使用时只需要调用这个函数即可:
自我介绍('xx','13888888888')
>>你好我叫xx
我的手机号是13888888888
三、函数参数
现在需要定义一个函数,这个函数能够完成2个数的加法运算,并且把结果打印出来,该怎样设计?
def add2num():
a = 11
b = 22
c = a+b
print (c)
>>33
#这里面只能计算11+22的值
为了让一个函数更通用,即想让它计算哪两个数的和,就让它计算哪两个数的和,在定义函数的时候可以让函数接收数据,就解决了这个问题,这就是 函数的参数:
def add2num(a, b): # 形式参数 , 形参(这里面的a,b)
c = a+b
print (c)
add2num(100, 200) # 实际参数, 实参(这里面的100,200)
有了函数的参数之后, 函数已经变得更好用一些了, 但是还不太够,我们需要有东西来接收这个函数,这就引出了下一个概念:函数返回值
四、函数返回值
定义了一个函数,完成了获取室内温度,那么函数当然应该把温度值返回给调用函数的人,只有调用者拥有了这个返回值,才能够根据当前的温度做适当的调整.
这就是函数返回值的作用
在上面例子中我们只能打印结果却不能用东西接收这一结果,这就需要另一个关键字:return
def add_a_b(a, b):
c = a+b
return c
t = add_a_b(3,5)
t
>>8
注意事项:
先看以下两个例子
def add2num(a, b):
c = a+b
return c
d = a*b
print(d)
>>8
def add2num(a, b):
c = a+b
d = a*b
print(d)
return c
add2num(3,5)
>>15
两个代码表示内容是一样的,那么为什么第一个只输出相加结果却没有进行下面的相乘呢?
是因为在函数当中,如果运行到return 关键字, 则函数终止相当于循环当中的break,因此当运行到return时后面代码将不在运行。
返回多个值
有的时候, 我们可能会需要函数同时返回多个值, 这个时候应该如何处理呢?
def divid(a, b):
shang = a//b
yushu = a%b
return shang, yushu
divid(7,3)
>>(2,1)
#返回两个值分别为两数的商和余数,那么我们可以用两个变量进行接收
s , y = divid(9,2)
s
>>4
y
>>1
练习:完成一个函数功能和sum相同
def sum_me(x_list):
n=0
for i in x_list:
n+=i
return n
五、函数的文档说明
def function(a,b):
"""函数的帮助文档
函数功能: 计算两个数字的乘积
参数说明: a 计算的第一个数
b : 计算的第二树
返回值: 两个数字相乘
"""
c = a +b
return a * b
定义好函数后在括号里按Shift+Tab可直接查看
六、调用函数时参数的顺序
def test(a, b, c):
print(a, b, c)
#可进行下面几种传递方法
test(3,5,1) # 位置参数
test(c = 1, b = 5, a = 3) # 关键字参数
test(3,5, c= 1) #先位置参数,再关键字参数
# 但是先进行位置参数,再关键字参数是不可以的,会报错
七、函数参数种类
7.1 位置参数
# 写一个幂运算函数
def power(x,y):
s = 1 # 连乘
for i in range(y):
s *= x
return s
power(x, n)函数有两个参数:x和n,这两个参数都是位置参数,
调用函数时,要按照函数设定的顺序依次传入的参数称为位置参数
7.2 默认参数
在上面定义幂函数时,我们想实现计算的都是二次方,要实现下面代码:
def power(x, n=2): # 因为我们最常计算的是2次方, 因此设置默认参数n=2
s = 1
while n > 0:
n = n - 1
s = s * x
return s
注意:必选参数在前,默认参数在后,否则会报错
默认参数降低了函数调用的难度,而一旦需要更复杂的调用时,又可以传递更多的参数来实现。无论是简单调用还是复杂调用,函数只需要定义一个。
八、局部变量与全局变量
8.1 局部变量
就是在函数内部定义的变量
变量的生效范围是在一个局部里面生效
不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
8.2 全局变量
如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量
在函数内部可以使用全局变量
# 定义全局变量
a = 200
def test1():
a = 300
print("在test1中a=", a)
def test2():
a = 400
print("在test2中a=", a)
#调用函数
test1()
test2()
print(a)
>>在test1中a= 300
在test2中a= 400
200
8.3 修改全局变量
一个自然而然的需求, 能不能再函数内部修改全局变量呢?
a = 100
def test1():
a += 1 # 在函数内部可以去使用全局变量,但是不能修改全局变量
return a
test1()
#这时会报错
a = 100
def test1():
global a # 改变全局变量a
a += 1
return a
test1()
>>101
总结:
- 在函数外边定义的变量叫做全局变量
- 全局变量能够在所有的函数中进行访问
- 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
- 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的
8.4 可变类型的全局变量
在函数中不使用global声明全局变量时不能修改全局变量的本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。
-
对于不可变类型的全局变量来说,因其指向的数据不能修改,所以不使用global时无法修改全局变量。
-
对于可变类型的全局变量来说,因其指向的数据可以修改,所以不使用global时也可修改全局变量。
如:
L = [1,2,3]
def f():
L.append(4)
f()
L
>>[1, 2, 3,4] #这时没有报错且已经改变了全局变量
练习:
写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
dic = {"k1": "v1v1", "k2": [11,22,33,44], 'k3':'gogogo','k4':'a'}
def f2(x_dic):
# 对字典中的每一个元素进行遍历
for key,value in x_dic.items():
if len(value) > 2:
x_dic[key] = value[:2]
f2(dic)
>>{'k1': 'v1', 'k2': [11, 22], 'k3': 'go', 'k4': 'a'}
#这时不需要用一个新变量来接收,因为字典是可变类型,所以此时已经将全局变量进行了改变
如果我们不想改动原数据,需要用新变量接收运行结果该怎么办呢?
def f2(x_dic):
#将原数据进行复制
new_dic = x_dic.copy()
# 对字典中的每一个元素进行遍历
for key,value in new_dic.items():
if len(value) > 2:
new_dic[key] = value[:2]
return new_dic
f2(dic)
>>{'k1': 'v1', 'k2': [11, 22], 'k3': 'go', 'k4': 'a'}
dic
>>{"k1": "v1v1", "k2": [11,22,33,44], 'k3':'gogogo','k4':'a'}
这时就得到我们想要的结果,原数据并没有改变,且又生成了新数据。
九、可变参数与关键字参数
可变参数, 就是当我们定义函数的时候还不知道具体需要传入多少个参数, 或者参数太长了不方便写.
可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
9.1 可变长参数
原来写一个函数计算一个列表的加和, 现在想要这样一个功能, 不需要传入列表, 可以传入任意个参数, 然后计算参数的加和。
例:
# 一个需求 , 可以计算用户传入进来的任意个数参数的和
def sum_me(*args): # * 会自动将你传入进来的所有参数打包成一个元组
n = 0 # 累加器
for i in args:
n += i
return n
sum_me(4,3,4,10,11)
>>32
这时我们传入参数就不需要以列表或者元组形式,可直接传入。
9.2 关键字参数
#参数前面加两个星号
def test(**kwargs):#传入参数必须以键值对方式,否则会报错
print(kwargs)
test(qqqq = 100, abc = '你好',c = [1,2,3],d = 66)
>>{'qqqq': 100, 'abc': '你好', 'c': [1, 2, 3], 'd': 66}
几个参数是可以结合使用的:
def test(a,b, *args , **kwargs):
print(a)
print(b)
print(args)
print(kwargs)
test(1,2,3,4,6,7,8,4,3,1, q = 666, hello = 'ok')
>>1
2
(3, 4, 6, 7, 8, 4, 3, 1)
{'q': 666, 'hello': 'ok'}