1 函数的定义
1.1 函数的定义
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。简言之,就是封装的功能代码
1.2 函数的语法
语法:
def 函数名(形参列表):
函数体(代码块, return)
注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。
1.3 为什么要使用函数?
(1).避免代码重用
(2).提高代码的可读性
2 函数的调用
函数名(实参列表)
2.1 函数使用的原则:
先定义,再调用
2.2 函数在定义阶段都干了哪些事?
#只检测语法,不执行代码
也就说,语法错误在函数定义阶段就会检测出来,而代码的逻辑错误只有在执行时才会知道
2.3 函数调用的三种形式
1 语句形式:foo()
2 表达式形式:3*len('hello')
3 当中另外一个函数的参数:range(len('hello'))
3 函数的返回值return,终止函数的执行
无return->None
return 1个值->返回1个值
return 逗号分隔多个值->元组
(1)如果函数没有return,则没有返回值,返回的就是None
(2)在函数中间或末尾写return,返回的是None
(3)在函数中写return值,返回一个值
(4)在函数中可以返回多个返回值,接受到的是元组
4 函数的参数
形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
写在函数声明的位置的变量叫形参
在函数调⽤的时候给函数传递的值. 叫实参
给函数传递信息的时候将实际参数交给形式参数的过程被称为传参.
4.1 实参(实参角度)
4.1.1 位置参数:
在传参过程中. 系统会默认按照形参位置把实参赋值到形参.
缺点:当函数的参数很多的时候,必须要记住每一个位置是什么
4.1.2 关键字参数
不需要记住每个参数的位置. 只要记住每个参数的名字就可以了
按照形参的名字给形参传值
4.1.3 混合参数:
既使用位置参数也用关键字参数
注意: 在使用混合参数的时候, 关键字参数必须在位置参数后⾯

4.2 形参(形参角度)
4.2.1 位置参数
按照位置来赋值
4.2.2 默认值参数
就可以给出函数参数的默认值. 在调⽤用的时候可以 给出具体的值, 也可以不给值, 使⽤用默认值.,解决繁琐的事情

调用的时候如果是男的就这样调用:regist(‘阿凡达’,‘11000’)
如果是女的这样调用:regist(‘阿凡达’,‘11000’,gender=‘女’)
注意, 必须先声明位置参数, 才能声明默认值参数. 默认参数通常应该定义成不可变类型
4.2.3 动态参数(可变长参数)
动态参数,也叫不定长传参,就是你需要传给函数的参数很多,不定个数
而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs
4.2.3.1 位置参数动态传参*args
位置参数, 按照位置进行传参。是*只能接收位置参数
例子:
def chi(*food): print("我要吃", food) chi("⼤米饭", "⼩米饭")
结果: 我要吃 ('⼤米饭', '⼩米饭') # 多个参数传递进去. 收到的内容是元组tuple
动态接收参数的时候要注意: 动态参数必须在位置参数后面
def chi(*food, a, b): print("我要吃", food, a, b) chi("⼤米饭", "⼩米饭", "⻩瓜", "茄⼦ ")
这时程序运⾏会报错. 因为前传递进去的所有位置参数都被*food接收了. a和b永远接收 不到参数,# 必须用关键字参数来指定
4.2.3.2 默认值参数动态传参
def chi(a, b, c='馒头', *food): print(a, b, c, food) chi("香蕉", "菠萝") # 香蕉 菠萝 馒头 (). 默认值生效 chi("香蕉", "菠萝", "葫芦娃") # 香蕉 菠萝 葫芦娃 () 默认值不生效 chi("香蕉", "菠萝", "葫芦娃", "口罩") # 香蕉 菠萝 葫芦娃 ('口罩',) 默认值不生效
-------->我们发现默认值参数写在动态参数前⾯. 默认值只有一种情况可能会生效.
顺序: 位置参数, 动态参数*, 默认值参数
4.2.3.3 关键字参数动态传参
在python中使用**来接收动态关键字参数
def func(**kwargs): print(kwargs) func(a=1, b=2, c=3) func(a=1, b=2)
结果: {'a': 1, 'b': 2, 'c': 3} {'a': 1, 'b': 2} 这个时候接收的是一个dict
最终顺序(*): 位置参数 > *args > 默认值参数 > **kwargs

4.2.3.4 另一种传参方式--打散
def fun(*args): print(args) lst = [1, 4, 7] fun(lst[0], lst[1], lst[2]) fun(*lst) # 可以使用*把一个列表按顺序打散 s = "臣妾做不到" fun(*s) # 字符串也可以打散, (可迭代对象)
在实参位置上给一个序列,列表,可迭代对象前面加个*表示把这个序列按顺序打散.


在形参的位置上的* 表示把接收到的参数组合成一个元组
如果是一个字典, 那么也可以打散. 不过需要用两个*
5 函数的注释
1 def chi(food, drink): 2 3 """ 这里是函数的注释 , 先写一下当前这个函数是干什么的 , 4 5 比如我这个函数就是一个吃 6 7 :param food: 参数 food 是什么意思 8 9 :param drink: 参数 drink 是什什么意思 10 11 :return: 返回的是什么东 12 13 """ 14 15 print(food, drink) 16 17 return "very good" 18 19 print(chi.__doc__) #查看函数注释
6 名称(命名)空间与作用域
6.1 什么是名称空间?
#名称空间:存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)
6.2 名称空间的加载、取值顺序
#1、python解释器先启动,因而首先加载的是:内置名称空间
#2、执行.py文件,然后以文件为基础,加载全局名称空间
#3、在执行文件的过程中如果调用函数,则临时产生局部名称空间
取值顺序:
在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间
6.3 作用域
(1)、作用域即范围
全局作⽤用域: 全局命名空间 + 内置命名空间
局部作⽤用域: 局部命名空间
(2)、作用域关系与函数的调用位置
作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,
6.4 Global()和locals()
通过globals()函数来查看全局作用域中的内容, 也可以通过locals()来查看局部作 ⽤用域中的变量量和函数信息

7 函数的嵌套
8 关键字global和nonlocal
global: 在局部访问全局中的内容
nonlocal: 在局部寻找外层函数中离他最近的那个变量
先我们写这样一个代码, 首先在全局声明一个变量, 然后再局部调⽤这个变量, 并改变这 个变量的值
1 a = 100 2 3 def func(): 4 5 global a # 加了个global表示不再局部创建这个变量了. ⽽而是直接使用全局的a 6 a = 28 7 8 print(a) #28 9 12 func() 13 14 print(a) #28

浙公网安备 33010602011771号