python之函数

1、函数的作用

函数就是将⼀段具有独⽴功能的代码块 整合到⼀个整体并命名,在需要的位置调⽤这个名称即可完成对应的需求,函数在开发过程中,可以更⾼效的实现代码重⽤。

2、函数的定义与调用

2.1、定义

def 函数名(参数):
	函数体

例如

def fun(a, b):
	return a-b;

2.2、调用

函数名(参数)

例如调用上面定义的函数

print(fun(3, 2))
输出
1

注意:
1、不同的需求,参数可有可无
2、在Python中,函数必须先定义后使用
3、函数必须被调用才会执行

3、函数参数的作用

可以是我们的程序更加灵活,需要注意的是,定义函数的时候的参数也叫形式参数(形参),调用时传入的参数叫实际参数,也叫做实参,且调用的时候传入的实参的个数必须与形参的个数相同

4、函数返回值的作用

在函数中,如果需要返回结果给⽤户需要使⽤函数返回值
语法

return 想要的返回值

注意,return后面的代码都不会再执行,因为return后就会退出当前函数,回到调用函数的地方继续向下执行

5、函数的说明文档

5.1、help

help(函数名):查看函数的说明文档(函数的解释说明的信息)

5.2、定义函数的说明文档

语法

	def 函数名(参数):
		"""说明文档的位置"""
		代码
		...

例如

def fun():
    """输出HelloWorld"""
    print("HelloWorld")

help(fun)
输出
Help on function fun in module __main__:

fun()
    输出HelloWorld

6、函数的嵌套调用

函数的嵌套调用就是在一个函数1里面又调用了函数2(函数2可以是函数1本身,也可以是其他函数)
函数的嵌套调用不难,我们只需要知道函数的执行流程即可
函数的执行流程:
1、调用函数,回到函数的定义处
2、自上而下执行函数体里的代码,遇到return或函数体里面的代码执行完后就退出函数
3、回到函数的调用处,继续向下执行下面的代码

看下面的代码

def fun1():
    print("fun1函数开始执行")
    print("fun1函数结束执行")

def fun2():
    print("fun2函数开始执行")
    fun1()
    print("fun2函数结束执行")

fun2()
输出
fun2函数开始执行
fun1函数开始执行
fun1函数结束执行
fun2函数结束执行

7、变量的作用域

变量的作用域就是指变量的生效范围,因此变量又分为局部变量和全局变量

7.1、局部变量

即定义在缩进里面的变量,只在缩进的那一段代码里生效,用于临时保存数据,当执行完缩进里面的代码后,局部变量就会被销毁

7.2、全局变量

所谓全局变量,就是指从定义处开始,到程序结束运行时都会生效的代码

接下来我们看两个例子

a = 100
print(a)

def fun1(a):
    a = 200
    print(a)

fun1(a)
print(a)

print("============================================")
b = [1, 2]
print(b)
def fun2(b):
    b[0] = 100
    print(b)

fun2(b)
print(b)
输出
100
200
100
============================================
[1, 2]
[100, 2]
[100, 2]

我们可以看到一个很有意思的现象,那就是当我们把a的值100传入进函数fun1时,a的改变也只是在函数外面改变,当函数结束运行时,原本a的值100并未发生改变,可是当我们传入一个列表a时,我们改变里面其中一个元素的值,列表a也跟着改变,这是为什么呢?

这时候我们就需要注意,当我们给函数传入参数时,传入的是一个值还是一个地址,接下来我们对上面的两个案例进行分析
首先是函数fun1()
当我们传入参数a时(我们假设这个a的地址为1111),我们是将a的值100传给函数的形参a,这个时候调用函数fun1的时候,函数就会在内存中单独开辟一个空间,并在这个空间中为形参分配一个内存空间,我们假设这个a内存空间的地址为2222,并将传入的实参给这个地址,如图所示
在这里插入图片描述
当我们执行到代码a = 200时,我们修改的只是函数开辟的这片空间里面a的值,地址为1111的a的值并未受到任何影响
在这里插入图片描述
此时我们输出的a的值也只是函数开辟的空间里面的值,当函数执行完后,函数临时开辟的这一片空间就会被销毁,我们再输出a的值,输出的就是全局变量,也就是地址为1111的这片空间的地址的值100

我们再说说函数fun2
同样,我们在刚开始就定义了一个全局变量b,由于它是列表,我们假设这一片连续的空间的地址为3333
当我们执行函数fun2时,此时传入的是列表b的地址3333,此时函数虽然会单独开辟一片空间用来执行函数里面的代码,却不会再为b单独开辟一个地址,而是就全局变量b的地址进行操作,修改的时候也是对3333这片连续的空间里面的值进行修改,所以在函数fun2执行完毕之后,我们再输出列表b里面每个元素的值,列表b也会发生改变

最后提一下,当我们有很多重名的变量名的时候,我们在调用某个变量名时,遵循的是就近原则,即距离调用处越近的,我们就越先调用,就好像上面的fun1时,我们在函数体内部打印a时,打印的是200而不是100

global函数

作用:声明某个变量为全局变量
语法

global 变量名
a = 100
print(a)

def fun1():
    # global a
    a = 200
    print(a)

fun1()
print(a)

当我们将global a这行代码注释掉后,控制台输出的是

100
200
100

当我们将注释取消后,控制台输出的是

100
200
200

由此我们可以观察到,global可以在函数体内部声明某个变量为全局变量,这样,当调用该变量时,就会调用刚开始定义的变量,这里我们需要注意的是,在函数体内部声明某个变量为全局变量时,改变量不能是函数的形参,否则将会报错,例如下面的代码

def fun1(a):
    global a
    a = 200
    print(a)

这样会报错

SyntaxError: name 'a' is parameter and global

8、函数的返回值

当我们想要在一个函数中返回多个值,那我们便可以这样书写

def 函数名(参数):
	代码1
	代码2
	retrun 返回值1, 返回值2

注意:
1、return a, b写法,返回多个数据的时候,默认是元组类型
2、return后面可以连接元组、列表、或字典,以返回多个值

9、函数的参数

9.1、位置参数

位置参数:调⽤函数时根据函数定义的参数位置来传递参数

def fun(name, age):
	print(f'名字:{name}, 年龄:{age}')
fun('TOM', 20)

注意:传递和定义参数的顺序及个数必须⼀致
当定义参数的个数与传入参数的个数不一致会报错

def fun(name, age):
    print(f"姓名:{name},年龄:{age}")

fun("Tom")
TypeError: fun() missing 1 required positional argument: 'age'

当传入参数的顺序与定义的顺序不一致时,可能不会报错,但会导致数据无意义

def fun(name, age):
    print(f"姓名:{name},年龄:{age}")
fun(19, "Tom")
姓名:19,年龄:Tom

9.2、关键字参数

函数调⽤,通过“键=值”形式加以指定。可以让函数更加清晰、容易使⽤,同时也清除了参数的顺序需求

def student_info(name, id, grade):
    print(f"学号:{id}")
    print(f"姓名:{name}")
    print(f"成绩:{grade}")
student_info("小明", grade=99, id=1111)
学号:1111
姓名:小明
成绩:99

注意:函数调⽤时,如果有位置参数时,位置参数必须在关键字参数的前⾯,但关键字参数之间不存在先后顺序

def student_info(name, id, grade):
    print(f"学号:{id}")
    print(f"姓名:{name}")
    print(f"成绩:{grade}")
student_info(grade=99, "小明", id=1111)

该代码报错

SyntaxError: positional argument follows keyword argument

这样也会报错

def student_info(name, id, grade):
    print(f"学号:{id}")
    print(f"姓名:{name}")
    print(f"成绩:{grade}")
student_info(99, name="小明", id=1111)
TypeError: student_info() got multiple values for argument 'name'

即如果我们要部分参数不写成关键字参数而留成位置参数,这些位置参数也必须是前面的,因为位置参数只能写在关键字参数前面

9.3、缺省参数

缺省参数也叫默认参数,⽤于定义函数,为参数提供默认值,调⽤函数时可不传该默认参数的值

def student_info(name, grade, ID="0000"):
    print(f"学号为{ID}的学生姓名是{name},成绩为{grade}")


student_info("小明", 99)
student_info("小红", 100, "1111")
学号为0000的学生姓名是小明,成绩为99
学号为1111的学生姓名是小红,成绩为100

注意:
1、所有位置参数必须出现在默认参数前,包括函数定义和调⽤,因为默认参数也是一种关键字参数
2、函数调⽤时,如果为缺省参数传值则修改默认参数值;否则使⽤这个默认值

9.4、不定长参数

不定⻓参数也叫可变参数。⽤于不确定调⽤的时候会传递多少个参数(不传参也可以)的场景。此时,可⽤包裹(packing)位置参数,或者包裹关键字参数,来进⾏参数传递,会显得⾮常⽅便。

9.4.1、包裹位置传递

语法:

def 函数名(*args):
	函数体

这里的args可以为其他合法的标识符(变量名)只不过写成这样是一个习惯

def fun(*args):
    print(args)
    
fun()
fun("Tom")
fun("Tom", 19)
()
('Tom',)
('Tom', 19)

注意:
1、传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为⼀个元组(tuple),args是元组类型,这就是包裹位置传递。
2、当有位置参数混合传递时,位置参数必须放在不定长参数的前面

def fun(*args, name):
    print(name, args)
fun("Tom", 19)
TypeError: fun() missing 1 required keyword-only argument: 'name'

9.4.2、包裹关键字传递

语法:

def 函数名(**kwargs):
	函数体

这里的kwargs可以为其他合法的标识符(变量名)只不过写成这样是一个习惯
即收集所有关键字参数返回一个字典

def fun(**kwargs):
    print(kwargs)
fun()
fun(name="Tom", age=18)
{}
{'name': 'Tom', 'age': 18}

注意:
1、同上面一样,当有位置参数时,位置参数的定义与调用都必须在不定长参数的前面

def fun(**kwargs, age):
    print(age, kwargs)
# fun()
fun(name="Tom", age=18)

报错

SyntaxError: invalid syntax

2、当有其他关键字参数参与时,这种传递方式不会收集该参数

def fun(age, **kwargs):
    print(age, kwargs)
# fun()
fun(name="Tom", age=18)
18 {'name': 'Tom'}

由上面我们可以知道,不定长参数其实都是一个组包的过程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值