函数的进阶
1. 可变长参数
(1)可变长形参
*args
用来接收多余的位置实参,args是人们约定俗成的一种写法。他把接收到的值按元组的形式存储。
这里args不是形参名,因为当有关键字实参为 args = 1 时,若形参中没有 args这个形参,则调用函数时会报错
也就是说 args = (a,b,c,d) 这样的形式
当没有任何实参传来时,程序不会报错,args就是空元组: args = ()
**kwargs
用来接收多余的关键字实参,kwargs也是人们约定俗成的一种写法。他把接收到的值按字典的形式存储。
这里kwargs不是形参名,因为当有关键字实参为 kwargs = 1 时,若形参中没有 kwargs这个形参,则调用函数时会报错
也就是说 kwargs = {'a':1,'b':2,'c':3,'d':4} 这样的形式
当没有任何实参传来时,程序不会报错,kwargs就是空元字典: kwargs = {}
*args 和 **kwargs 一起使用就可以接收全部的实参
(2)可变长实参
*
用来把星号后的容器数据类型(列表,元组,集合)中的数据提取出来,依次传给位置形参
**
用来把星号后的字典中的键值对提取出来转化成关键字实参,依次传给和关键字对应的形参
2. 函数的对象
python中一切皆对象
对象能够完成这四件事情
能被引用
当作容器类数据类型的元素
当作函数的实参
当作函数的返回值
def register():
print('register')
def login():
print('login')
def withdraw():
print('wightdraw')
def shopping():
print('shopping')
func_dict = {
'1': register,
'2': login,
'3': withdraw,
'4': shopping,
}
print('''
1 注册
2 登录
3 提现
4 购物
''')
while True:
choice = input('请选择你需要的功能(输入q退出):')
if choice == 'q':
break
func_dict[choice]() #此时的 func_dict[chioce] 相当于上面的各个函数名,可以加个括号对上面的函数进行调用
3. 函数的嵌套
函数的嵌套就是函数里面有函数
函数内部定义的函数,外部不能直接调用
#定义函数,只检测语法,不会执行代码
def f1():
print('from f1')
def f2():
print('from f2')
f2() # 在同一位置时,调用函数必须放在定义之后
res = f1()
4. 名称空间和作用域
变量名/函数名/内置方法名 都存放在名称空间
1. 名称空间
- 名称空间的生成顺序:
- 内置名称空间:python解释器启动的时候就有了
- 全局名称空间:执行文件代码的时候才会有全局
- 局部名称空间:函数调用的时候才会有局部
python解释器搜索名称的顺序:
先从当前位置寻找,找不到再按照下面的这种顺序;搜索不会按下面的逆序搜索(只会在当前或者然继续搜索)
局部 ——》全局——》内置——》报错
(1)内置名称空间
- 存储了python解释器自带内置方法(print/len/list/str/dict 等)的名称
(2)全局名称空间
- 存储了除了内置和局部名称的其他名称
(3)局部名称空间
函数内部定义的都叫局部
局部名称空间存储了局部中的各名称
2. 作用域(发挥作用的区域)
(1)全局作用域
包含:内置名称空间 + 全局名称空间
(2)局部作用域
只包含:局部名称空间
3. 改变全局和局部的三种方法
1. 全局作用域的 x 和局部作用域的 x 没有半毛钱的关系 2. 局部作用域1的x和局部作用域2的x也没有任何关系,即使局部作用域1和局部作用域2再同一个局部作用域下
(1)可变数据类型无所不能
- 要用就用可变数据类型
- 但不能以定义的方式改变该数据类型
#所有可变数据类型均可打破上述一切规则
lt = [10]
def f1():
lt.append(12)
# lt = [0] 这种方法不行
lt[0] = 11
f1()
print(lt) # 打印结果: lt 为 [11,12]
(2)global
- global 将局部名称变成全局名称
x = 10
def f1():
global x # 让global以下的局部的x变成全局的x
x = 20
f1()
print(x) # 打印结果:x为20
(3)nonlocal
- nonlocal 将当前局部名称变成本层的顶层局部名称
x = 10
def f1():
def f2():
def f3():
nonlocal x # nonlocal让x成为顶层函数的局部,不是让他成为全局 # 压根没有应用情景,尽量不要嵌套函数
x = 1
x = 2
f3()
print(x) # 打印结果: x为1