概述
注意:
1、返回值可以是一个常量、变量或者表达式。
2、如果函数中没有return语句,那么该函数就没有返回值。
3、函数内部修改全局变量的值,使用global关键字进行声明。
一、函数
在程序开发过程中,使用函数可以提高编写的效率以及代码的重用性。即:函数就是封装代码,从而提升代码的重用性。
函数的使用包含两个步骤:
第一步:定义函数——就是把代码封装到函数内部
第二步:调用函数——用来执行封装好的代码
也就是说,函数要先定义,然后才能调用。
二、函数定义和调用
1、函数定义
def 函数名( ):
函数内部要封装的代码
其中,def是define的缩写,函数名就是给封装的代码起个名字,需要注意的是,函数名起的时候要能够表达所封装的代码功能(用途),即:见名知意。
函数名的命名要符号标识符的命名规则。
2、函数调用
通过函数名( )即可完成函数的调用。
注意:通常,函数定义部分应该和其它代码之间空两行。例如
def my_func1():
print("*" * 10)
# pycharm里按ctrl+alt+L可以看到代码这里自动空出来两行
# 这样是为了更方面看函数部分,与非函数部分
my_func1()
结果:
**********
三、函数的参数——形参和实参
函数的主要功能是封装代码,因此,一个已经写好的函数,不应该来回再去修改它内部的代码。但是需求是不断变化的,代码要实现重复用,就必须增大它的灵活性,因此,可以通过函数的参数来实现函数代码的灵活性。
语法:
def 函数名(参数1,参数2,...): #这里是定义函数,参数是形参
函数内部代码
函数名(参数1对应的值,参数2对应的值,...) #这里是函数调用,参数是实参
注意:
(1)形参:定义函数的时候,括号里面的参数。用来接收参数用的,在函数内部作为变量使用。形参必须是变量。
(2)实参:调用函数的时候,括号里面的参数。用来把数据传递到函数内部用的。实参可以是常量、变量、表达式。
(3)定义函数的时候,形参没有值,只是一个变量名。只有调用函数的时候,通过实参把值实时的赋给形参。同时,函数在定义的时候,有几个参数,那么调用的时候就要对应几个值。即:函数在调用和定义的时候,参数的数量要一一对应。
举例:返回两个参数中的最大值。通过该题来说明实参可以是变量、常量、表达式。
# 1、实参是常量
def max_num(a, b):
if a > b:
return a
else:
return b
print(max_num(3, 11)) # 实参是常量
结果:
11
# 2、实参是变量
def max_num(a, b):
if a > b:
return a
else:
return b
num1 = int(input("请输入一个整数:"))
num2 = int(input("请输入一个整数:"))
print(max_num(num1, num2)) # 实参是变量
结果:
请输入一个整数:3
请输入一个整数:11
11
#3、实参是表达式
def max_num(a, b):
if a > b:
return a
else:
return b
print(max_num(1 + 2, 5 + 6)) # 实参是表达式
结果:
11
图解说明传参过程:以形参是常量为例,其它的,比如形参是变量以及表达式,原理跟这个一样。
四、函数的返回值——通过return关键字来实现
首先需要知道的是,函数的返回值通过return来实现,如果一个函数中没有使用return语句,那么这个函数就没有返回值,即使打印出来结果也为None。
所谓函数的返回值就是说,函数执行结束后,会返回一个结果给调用者,以便调用者拿到这个结果之后进行后续操作(比如进行判断或者循环操作)。函数通过return返回给调用者一个值,return后面可以是常量、变量或者表达式。
在程序开发过程中,有些函数有返回值,有些函数没有返回值,例如:print( )函数,是没有返回值的,对于没有返回值的函数,怎么使用的?直接就是函数名加参数的方式,即:函数名(参数),比如:输出hello,就是print("hello "),此时hello就是它的参数。
再比如,下面这个函数,也是没有返回值的。
def my_sum(a, b):
print(a + b)
my_sum(1, 2) # 函数名( )——调用这个函数
结果:
3
因为它没有返回值,所有即使强制打印,结果也为None。
def my_sum(a, b):
print(a + b)
result = my_sum(1, 2) # 因为my_sum函数里面没有使用return语句,所以就没有返回值
print(result)
结果:
3
None
而我们上面写的计算两个数中的最大数,这个函数是有返回值的,因为有关键字return。
再比如,计算两个数相加,它也是一个有返回值的函数。
def my_sum(a, b):
return a + b # 把a+b的结果,返回给调用者
result = my_sum(1, 2) # 调用my_sum函数,所以这里就是调用者。
# 此时,result将得到函数的返回值
print(result) # 将结果显示出来
结果:
3
解析:return的作用就是把函数的结果返回给调用者。也就是说,哪调用了这个函数,就把结果给谁。上题中,my_sum( 1,2)这里调用了这个函数,所以return就会把return后面的东西返回给它。此时,这个调用者又把这个结果用一个变量接收了一下,(或者说,把结果赋给result这个变量)。然后print这个变量就能把结果显示出来了。
当然也可以不使用这个变量进行接收,也可以直接print(my_sum(1, 2))。增加这个result变量的目的呢只是让代码看起来更舒服一些。
注意:
return后面如果还有代码,那么程序在执行的时候是不会报错的,但不会执行return后面的代码。即:return后面的代码,不会被执行。
例如:该题中就不会输出hello。
def my_sum(a, b):
return a + b
print("hello") # 不会输出hello
result = my_sum(1, 2)
print(result)
结果:
2
有返回值的函数练习:
例如:计算两个数的和,如果和等于50就输出50,如果大于50就输出比50大,如果小于50就输出比50小。
def my_sum(a, b):
return a + b
result = my_sum(1, 2)
if result == 50:
print(result)
elif result < 50:
print("比50小")
else:
print("比50大")
结果:
比50小
# 改进,把这两数不写死,由用户输入
def my_sum(a, b):
return a + b
num1 = int(input("请输入num1:")) # 用input()输入
num2 = int(input("请输入num2:"))
result = my_sum(num1, num2)
if result == 50:
print(result)
elif result < 50:
print("比50小")
else:
print("比50大")
结果:
请输入num1:30
请输入num2:40
比50大
小结:函数中使用return的意义:
在程序开发的过程中,为了让函数能够更好的适应需求的变化,通常程序设计时候会有个原则,可以修改函数外部的代码,但函数定义后,不应该修改函数内部的代码。这样函数的封装才会显得更加完整和独立,而且在使用的过程中也才会显得更加的灵活。
练习:定义一个函数,名字叫做my_func,它有两个参数a,b,如果a能被b整除,那就返回True,否则False。
解析:什么叫a能被b整除?首先,a能被b整除,又可以叫b能整除a。就是说a除以b。即:a是被除数,b是除数。比如:12➗4=3,就叫12能被4整除。
解答:法1:把判断放到函数内部,最后的True、False是用return来返回。
# 法1:把if判断放函数里
def my_func(a, b):
if a % b == 0:
return True
else:
return False
num1 = int(input("请输入num1:"))
num2 = int(input("请输入num2:"))
result = my_func(num1, num2)
print(result)
结果:
请输入num1:20
请输入num2:10
True
请输入num1:5
请输入num2:3
False
法2:把判断放到函数外部,最后的True、False是用print进行输出。
# 法2:把if判断放函数外面
def my_func(a, b):
return a % b
num1 = int(input("请输入num1:"))
num2 = int(input("请输入num2:"))
result = my_func(num1, num2)
if result == 0:
print("True")
else:
print("False")
结果:
请输入num1:20
请输入num2:10
True
请输入num1:5
请输入num2:3
False
五、函数的嵌套
顾名思义,就是一个函数内部又调用了另外一个函数。
def func1():
print("我是函数1")
def func2():
func1() # 函数2调用了函数1
print("我是函数2")
func2() # 程序第一条执行的语句
结果:
我是函数1
我是函数2
解析代码:函数2中先调用了函数1,然后再输出自己是函数2,所以在执行的过程中,会先执行函数1中的代码,执行完之后才会接着刚才调用的地方接着往下执行。
六、变量的作用域、作用范围
变量的作用域可以分为:全局变量和局部变量。
在哪定义 | 谁可以用 | 生命周期 | 备注 | |
全局变量 | 函数外部 | 所有函数内部都可以用 | 整个程序执行结束后,才被回收 | 尽量少用 |
局部变量 | 函数内部 | 只能在当前这个函数内部使用 | 函数调用执行完就被系统回收了 |
1、全局变量
函数外部定义的变量,就是全局变量。所有函数内部都可以使用这个变量。(为了保证所有的函数都能使用到全局变量,一般都是将全局变量的定义放到所有函数的上面。方便阅读代码)但是需要注意的是,尽量少定义全局变量,尤其是,能用局部变量解决的问题,那就用局部变量来解决,尽量不要通过全局变量去解决。因为全局变量是对整个程序都有效,所以如果遇到一个程序中函数较多时,处理起来会比较麻烦,导致程序不好维护。 除此之外,全局变量因为是对整个程序有效,所以全局变量会从定义了之后就存在内存中,一直到程序执行结束后,和程序一起从内存中消失(也就是被系统回收)。——程序全部运行完,才消失。
例如:代码中两个空行,是pycharm中的标格式。
a = 1 # 这里的a是一个全局变量,所有函数都可以使用
def func1():
print(a)
def func2():
print(a)
func1()
func2()
结果:
1
1
2、局部变量
函数内部定义的变量,就是局部变量。局部变量只能在当前这个函数内部使用。不同的函数,可以定义相同的局部变量名字,彼此之间不会产生影响。在函数内部使用局部变量,主要是用来临时保存一些函数内部使用到的数据。除此之外,函数在执行结束后,函数内部的局部变量就会被系统回收。也就是说,局部变量从调用函数的时候开始在内存中出现,函数调用完毕后,局部变量就会从内存中消失。但是,如果一个函数内部虽然定义了局部变量,但是这个函数没被调用,那么这个局部变量也就不会在内存中存在。
即:
(1)函数中定义了局部变量——函数被调用——局部变量会存到内存中——函数执行完毕——局部变量消失,被系统回收。——函数一调完就么了。
(2)函数中定义了局部变量——函数没被调用——内存中没这个局部变量。
def func1():
a = 1 # 这里的a是一个局部变量,只属于func1这个函数
print(a)
def func2():
a = 2
print(a) # 这里的a是一个局部变量,只属于func2这个函数
func1() # 调用func1函数,局部变量a出现了,调用完毕后,a消失了
结果:
1
七、函数内部修改全局变量的值—global关键字
1、局部变量跟全局变量同名怎么办?
首先,先注意一个问题:如果函数内部定义的局部变量跟全局变量同名怎么办?那么在这个函数内部,使用的就是局部变量的值。因为这个重名会把全局变量覆盖掉,所以,只能使用局部变量。而函数内部如果没有定义同名的变量,那就可以使用全局变量,比如下面的my_func2( )。
a = 1 # 定义一个全局变量a
def my_func1():
a = 10 # 这里不是给全局变量赋值,而是定义了一个局部变量,只是名字和全局变量重名而已。
print(a) # 输出局部变量a的值
a += 1 # 这里改的是局部变量a的值
def my_func2():
print(a) # 输出全局变量a的值
my_func1()
my_func2()
print(a) # 输出全局变量a的值
结果:
10
1
1
2、局部变量中修改全局变量的值
如果要在函数内部修改全局变量的话,就必须使用global关键字进行声明。
格式:
def 函数名( ):
global 全局变量的名
全局变量名=值
例如:使用global a,就是将局部变量a改为全部变量a,此时,在这个函数内部,所有的a都是全局变量。
a = 1 # 定义一个全局变量a
def my_func1():
global a # 将局部变量a,变成全局变量a,也就是说,在这个函数内部,所有的a都是全局变量。
a = 10 # 修改全局变量的值
print(a)
def my_func2():
print(a) # 输出全局变量a的值
my_func1() # 调用了my_func1,此时,全局变量的值将被改为10
# 也就意味着,下面的代码中,a的值都是10
my_func2()
print(a) # 输出全局变量a的值
结果:
10
10
10
上面的代码中,调用了my_func1,此时,全局变量的值将被改为10,也就意味着,剩下的代码中,a的值都是10。
但是,如果不调用my_func1这个函数,那么a的值就还是1,因为没有执行值修改的代码,所以值也就不会变 。
a = 1 # 定义一个全局变量a
def my_func1():
global a # 将局部变量a,变成全局变量a
a = 10 # 修改全局变量的值
print(a)
def my_func2():
print(a) # 输出全局变量a的值
my_func2()
print(a) # 输出全局变量a的值
结果:
1
1
3、在函数内部修改局部变量的值
正常的修改即可。不需要global去声明。
八、形参和实参的值传递
这里就要涉及函数、变量、参数掺杂在一起的问题了,注意区分函数的形参、实参、以及全局变量、局部变量、实参和形参重名的含义了。
注意区分:什么是单纯的在局部变量中修改全局变量的值,什么是修改形参的值!虽然函数中的形参,本质上来说也是局部变量,但是,函数带参数和不带参数时候,结果是不一样的。
例如:下面这个函数不带参数,所以确切的说,是单纯的在局部变量中修改全局变量的值。
a = 0 #全局变量
def b():
a += 1 # a放函数里,那就叫局部变量,所以这里就是全局变量和局部变量同名
print(a) # 同名之后再进行操作,那就是,在局部变量里修改全局变量的值
# 此时要用global,但它没用,所以报错
b()
结果:
a += 1
UnboundLocalError: local variable 'a' referenced before assignment
报错是因为,没加global关键字进行声明。正确的写法:
a = 0
def b():
global a # 将a声明为全局变量,所以b函数内所有的a现在开始,都是全局变量
a += 1
print(a)
b()
结果:
1 # 由0变1,说明修改成功
再梳理下:什么叫修改形参的值。
例如:下面这个函数带了参数,这个参数叫形参,本质上来说也是局部变量。
def my_func1(a): # 这里的 a 是函数my_func1的形参
# 本质上也就是一个属于函数内部的【局部变量】
a += 1 # 修改形参的值,本质上就是修改局部变量a的值
print(a) # 输出形参a
a = 10 # 全局变量a,值为10
my_func1(a) # 把全局变量a作为实参,去调用函数my_func1
print(a) # 输出全局变量a的值
结果:
11
10
代码中一一共出现了两个变量:全局变量a、形参a(本质上也就是局部变量)。
上面a太多了,很容易分不清,把形参a换成b来写,代码会清晰明了很多。
def my_func1(b): # 形参b,本质上也就是一个【局部变量】
b += 1 # 修改形参的值,本质上就是修改局部变量的值
print(b) # 输出形参b
a = 10 # 全局变量a,值为10
my_func1(a) # 把全局变量a作为实参,去调用函数my_func1
print(a) # 输出全局变量a的值
结果:
11
10
1、修改形参的值——对实参的影响
当形参为不同的数据类型时,修改形参的值,对实参值的影响也是不同的。有的形参修改后,实参不变;有的形参修改后,实参会变。下面将分别进行说明。
第一种情况:实参的值不变
当形参的类型为数字或者字符串时,如果在函数内部即使修改了形参的值,实参的值也不会发生任何变化。
例如:当形参为数字时
a = 10 # 全局变量a,值为10
def my_func1(b): # 形参b,本质上也就是一个【局部变量】
b += 1 # 修改形参的值
print("修改形参后,【形参】的值为:%d" % b) # 输出形参b
print("实参的值为:%d" % a)
my_func1(a) # 把全局变量a作为实参,去调用函数my_func1
print("修改形参后,【实参】的值为:%d" % a) # 修改形参后,再次输出实参的值
结果:
实参的值为:10
修改形参后,【形参】的值为:11
修改形参后,【实参】的值为:10
#小结:当形参为【数字】时候,形参修改后,实参的值不变!
可以看见,10作为实参去调用函数之后,进行了加1操作,但是再次输出a时,a的值依然的是10,所以可以说,当形参的类型为数字的时候,在函数内部即使修改了形参的值,实参的值也不会受到影响。
例如:当形参为字符串时
a = "hello" # 全局变量a,值为10
def my_func1(b): # 形参b,本质上也就是一个【局部变量】
b = b.replace("h", "a") # 修改形参的值,把字符串中的h替换为a
print("修改形参后,【形参】的值为:%s" % b) # 输出形参b
print("实参的值为:%s" % a) # 也是全局变量、也是函数的实参
my_func1(a) # 把全局变量a作为实参,去调用函数my_func1
print("修改形参后,【实参】的值为:%s" % a) # 输出实参a的值
结果:
实参的值为:hello
修改形参后,【形参】的值为:aello
修改形参后,【实参】的值为:hello
再比如,把b = b.replace("h", "a")改为:b = "123"
结果:
实参的值为:hello
修改形参后,【形参】的值为:123
修改形参后,【实参】的值为:hello
#小结:当形参为【字符串】时候,形参修改后,实参的值不变!
第二种情况:实参的值会变
当形参的类型为列表、集合、字典时,如果在函数内部修改了形参的值,那么实参的值也将会发生变化。 (元组的话可以不用管,因为元组的成员不能增加、删除、修改,所以也就不存在修改形参值的说法了)
例如:当形参为列表时
a = [1, 2, 3, "hello"] # 全局变量
def func1(b): # 形参b,也是函数func1的局部变量
b[0] = 10 # 修改形参的值
print("修改形参后,【形参】的值为:%s" % b) # 输出形参b
print("实参的值为:%s" % a) # 输出全局变量a的值、也是函数的实参
func1(a) # 把全局变量a作为实参,去调用函数func1
print("修改形参后,【实参】的值为:%s" % a) # 输出实参a的值
结果:
实参的值为:[1, 2, 3, 'hello']
修改形参后,【形参】的值为:[10, 2, 3, 'hello']
修改形参后,【实参】的值为:[10, 2, 3, 'hello']
#可以发现,形参为列表时,修改了形参的值,实参也会变。
把上面的形参b,改成形参a ——让形参实参同名、或叫让局部变量和全局变量同名
a = [1, 2, 3, "hello"] # 全局变量
def func1(a): #把原来的b改成a,此时叫, 形参a————形参和实参同名
a[0] = 10 # 修改形参的值
print("修改形参后,【形参】的值为:%s" % a) # 输出形参a
print("实参的值为:%s" % a) # 输出全局变量a的值、也是函数的实参
func1(a) # 把全局变量a作为实参,去调用函数func1
print("修改形参后,【实参】的值为:%s" % a) # 输出实参a的值
结果:
实参的值为:[1, 2, 3, 'hello']
修改形参后,【形参】的值为:[10, 2, 3, 'hello']
修改形参后,【实参】的值为:[10, 2, 3, 'hello']
结果也是一样。所以可知,形参值的修改对实参的有没有影响不是看它俩同不同名,而是看形参是什么数据类型。但原则上,最好还是不要同名,这样自己看代码时候也比较清晰明了,不容易搞混。
再比如:当形参为集合时
a = {1, 2, "你好"} # 全局变量
def func1(b): # 形参b,也是函数func1的局部变量
b.remove("你好") # 删除元素“你好”
print("修改形参后,【形参】的值为:%s" % b) # 输出形参b
print("实参的值为:%s" % a) # 输出全局变量a的值、也是函数的实参
func1(a) # 全局变量a作为实参,去调用函数func1
print("修改形参后,【实参】的值为:%s" % a) # 输出实参a的值
结果:
实参的值为:{1, 2, '你好'}
修改形参后,【形参】的值为:{1, 2}
修改形参后,【实参】的值为:{1, 2}
注意:如果类型是集合,在修改形参的时候,集合的操作只能是对集合自己的操作,如果是原集合和其它集合进行的操作,比如,求并集、交集、差集等,实参的值都是不会变化的。
例如:集合和其它集合求交集——不会对实参造成影响
a = {1, 2, "你好"} # 全局变量
def func1(b): # 形参b,也是函数func1的局部变量
c = {1, 2}
b = b & c
print("修改形参后,【形参】的值为:%s" % b) # 输出形参b
print("实参的值为:%s" % a) # 输出全局变量a的值、也是函数的实参
func1(a) # 全局变量a作为实参,去调用函数func1
print("修改形参后,【实参】的值为:%s" % a) # 输出实参a的值
结果:
实参的值为:{1, 2, '你好'}
修改形参后,【形参】的值为:{1, 2}
修改形参后,【实参】的值为:{1, 2, '你好'}
# 可以看到求交集,实参无影响。
例如:当形参为字典时
a = {"name": "张三", "age": 18}
def func1(b): # 形参b,也是函数func1的局部变量
b["name"] = "李四" # 把张三改为李四
print("修改形参后,【形参】的值为:%s" % b) # 输出形参b
print("实参的值为:%s" % a) # 输出全局变量a的值、也是函数的实参
func1(a) # 全局变量a作为实参,去调用函数func1
print("修改形参后,【实参】的值为:%s" % a) # 输出实参a的值
结果:
实参的值为:{'name': '张三', 'age': 18}
修改形参后,【形参】的值为:{'name': '李四', 'age': 18}
修改形参后,【实参】的值为:{'name': '李四', 'age': 18}
小结:不同的数据类型,修改形参时,可进行的操作。
修改形参时,可进行的操 | 对实参的影响 | |
数字 | 加减乘除、求余、求幂、整除 | 无影响 |
字符串 | 替换(replace) | |
列表 | 增加、删除、修改(append、extend、insert、pop、remove、clear、列表名[索引]=值) | 实参的值会变 |
集合 | 增加、删除(add、update、pop、remove、discard、clear)。 注意:只能是对集合自己的操作,和其它的集合求并集交集等这些不行。 | |
字典 | 增加、删除、修改(字典名[“键”]=值,如果存在就修改,如果不存在就添加、update(字典)、pop、popitem、clear) | |
元组 | 无 |
九、缺省参数
也就是说,函数在定义的时候,可以给形参定义一个默认值,(这种参数也叫缺省参数)。当函数调用的时候,如果没有提供实参,那么形参就会使用这个缺省值。需要注意的是,在定义的时候,必须要把带有默认值的参数放到最后,不能把它写到没有默认值的参数前面。
例如:
def func1(a, b=1): # 正确写法
def func1(b=1, a): # 错误写法
十、匿名函数——lambda
可以用来精简代码,常用来写特别小型的函数。
格式:
lambda 参数1,参数2,.....:函数要执行的代码
需要注意的是:它只有一条语句,且这条语句要有一个具体的返回值。
例如:给两数求和。
#常规的做法
def my_sum(a, b):
return a + b
print(my_sum(3, 5))
结果:
8
#利用lambda
my_sum = lambda a, b: a + b
print(my_sum(3, 5))
结果:
8
#或写成
my_sum = (lambda a, b: a + b)(3, 5)
print(my_sum)
结果:
8
例如:两数比较大小,输出最大的那个数。
#常规的写法
def my_max(a, b):
if a > b:
return a
else:
return b
result = my_max(3, 5)
print(result)
结果:
5
#利用lambda
result = (lambda a, b: a if a > b else b)(3, 5)
print(result)
结果:
5
最后
以上就是淡然身影为你收集整理的python之函数、函数的定义与调用、函数的参数(形参、实参)、函数的返回值—return关键字、变量作用域(全局变量、局部变量)、函数内部修改全局变量的值—global关键字、lambda匿名函数一、函数二、函数定义和调用三、函数的参数——形参和实参四、函数的返回值——通过return关键字来实现五、函数的嵌套六、变量的作用域、作用范围七、函数内部修改全局变量的值—global关键字八、形参和实参的值传递九、缺省参数十、匿名函数——lambda的全部内容,希望文章能够帮你解决python之函数、函数的定义与调用、函数的参数(形参、实参)、函数的返回值—return关键字、变量作用域(全局变量、局部变量)、函数内部修改全局变量的值—global关键字、lambda匿名函数一、函数二、函数定义和调用三、函数的参数——形参和实参四、函数的返回值——通过return关键字来实现五、函数的嵌套六、变量的作用域、作用范围七、函数内部修改全局变量的值—global关键字八、形参和实参的值传递九、缺省参数十、匿名函数——lambda所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复