函数-2
目录
函数的参数
- 参数简介
- 位置参数
- 关键字参数
- 默认值参数
- 可变长参数
- 命名关键字参数
名称空间
作用域
global 与 nonlocal 关键字
函数名的多种使用方式
函数的参数
-
参数的简介
函数的参数分为形参和实参两大类
形参:在定义函数时,所需定义的值。本质就是变量名,用来接收外部传来的值。
实参:在调用函数时,所需输入的值。本质就是数据值(可以是常量,变量,表达式或三者的结合)
在函数调用阶段形参会临时与实参进行绑定 函数运行结束立刻解除
-
位置参数
按照顺序定义参数,从左往右依此定义形参和实参。
形参和实参的位置是一一对应的
-
关键字参数
在调用函数时,实参可以是kv键值对,又称为关键词参数。这样的实参可以不按照顺序来定义实参,仍能定义形参。
实参也可以是按位置或按关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值
-
默认值参数
默认值参数就是在函数定义阶段,( ) 中以 ... = ... 的形式填写的形参
1.在函数定义阶段就给形参绑定值 后续调用阶段就可以不传
2.调用阶段不传值就使用默认的 传了就用传了的
3.需要遵循前面总结的规律(简单的在左边 复杂的在右边) -
可变长参数
可变长形参与实参可以随意传值
在形参中 * 的作用:
接受多余的位置参数组合成元组的形式赋值给* 后面的变量名
在形参中 ** 的作用
接收多余的关键字参数并组织成字典的形式赋值给 ** 后面的变量名实参中的
*会获取可迭代对象的 key(索引/键值)由于获取的是可迭代对象的 key,所以函数的形参可以为位置参数或可变参数
1. 形参为位置参数:
def foo(n1, n2, n3, n4, n5):
return n1, n2, n3, n4, n5
d = {'n1': 5, 'n2': 6, 'n3': 7, 'n4': 8, 'n5': 9}
print(foo(*d)) # ('n1', 'n2', 'n3', 'n4', 'n5')
2. 形参为可变参数:
def fu(*n):
print(n)
d = {'n1': 5, 'n2': 6, 'n3': 7, 'n4': 8, 'n5': 9}
print(fu(*d)) # ('n1', 'n2', 'n3', 'n4', 'n5')
"""将实参中的字典对象换成列表、元组或者字符串对象,都是可以的"""
实参中的**会获取可迭代映射的 value
由于获取的是可迭代对象的 value,所以函数的形参只能为关键字参数,即参数的个数和名称都是固定的
def foo(n1, n2, n3, n4, n5):
return n1, n2, n3, n4, n5
d = {'n1': 5, 'n2': 6, 'n3': 7, 'n5': 8, 'n4': 9}
print(foo(**d)) # (5, 6, 7, 9, 8)
如果我们要调用的函数不是关键字形参,或者关键字形参与传入的实参无法一一对应,那就会报错
- 命名关键字参数
def func(a,b,*args):
pass
func(1,2)
func(a=1,b=2)
func(1,b=222)
'''需要形参在传实参的时候 必须按照关键字参数才可以'''
在形参*args的后面
def func(a, b, *args, c):
print(a, b, args, c)
func(1,2,3,4,5,6,7) # 报错
func(1, 2, 3, 4, 5, 6, c=666)
# 如果形参中还有**kwargs 那必须在它的前面
def func(a,b,*args,c,**kwargs):
pass
func(1,2,3,4,5,6,c=123,name='jason')
名称空间
名称空间就是用来存放变量名和数据值之间绑定关系的地方
| 名称空间分类 | 各个名称空间作用 | 作用域 | 存活周期 |
|---|---|---|---|
| 内置名称空间 | python解释器运行就会立刻创建的空间,写代码过程中可以直接使用的名字都在该空间中 | 在程序任意位置都可以使用(全局有效) | 解释器运行(创建),解释器关闭(销毁) |
| 全局名称空间 | py文件运行代码过程中产生的名字都会存入该空间 | 在程序任意位置都可以使用(全局有效) | py文件运行(创建) , py文件结束(销毁) |
| 局部名称空间 | 函数体代码运行过程中产生的名字都会存入该空间 | 在各自的局部空间可以使用(局部有效) | 函数体代码运行(创建) 函数体代码结束(销毁 |
名称的查找顺序
-
当前在全局名称空间的时候,查找循序是先是全局空间再是内置空间
-
当前在局部名称空间时,先是局部名称空间,再是全局名称空间,最后是内置名称空间
名字的顺序不能颠倒,只能是局部——全局——内置
查找名字前,要先确定在哪个内存空间
- 局部名称空间的复杂程度
- 各自局部名称空间默认的情况下不能彼此共享名字
def func1():
name = 'jason'
print(age)
def func2():
age = 18
print(name)
func1()
func2()
# 直接报错
- 在嵌套模式:
# x = 1
#
#
# def func1():
# x = 2
# def func2():
# x = 3
# def func3():
# # x = 4
# print(x)
# func3()
# func2()
# func1()
name = 'jason'
def func():
print(name)
name = 'jasonNB'
func()
函数在定义阶段其实名字的查找顺序就已经固定死了
global与nonlocal关键字
# money = 999
# def func():
# global money # 声明 局部名称空间中的money操作的是全局的money
# money = 1000
# print(money) # 1000
正常情况下 局部名称空间里面出现新的名字会在局部名称空间中存储
但是有时候需要在局部名称空间中修改全局名称空间的名字
# l1 = [1, 2, 3, 4, 5]
# s = '$jason$'
# def func():
# global s
# s = 'jason'
# res = s.strip('$')
# l1.append(113123)
# l1.append(666)
# func() # jason
# print(l1) # [1, 2, 3, 4, 5, 113123, 666]
局部修改全局名称空间中不可变类型的数据 需要使用关键字global声明
如果是可变类型 则无需关键字声明
def func1():
x = 1
l1 = [1,2]
def func2():
# nonlocal x
x = 999
l1.append(666)
func2()
print(x)
print(l1)
func1()
nonlocal 在内存局部名称空间修改外层局部名称空间中的不可变类型
函数名的多种使用方式
- 1.函数名也可以被用来多次赋值(函数名与变量名使用一致)
def func():
print('from func')
name = func
name()
name1 = name
name1()
- 2.函数名还可以当做函数的实参
def func():
print('from func')
def index(a):
print(a)
a()
index(123)
name = 'jason'
index(name)
index(func)
-
- 函数名还可以当做函数的返回值
def func():
print('from func')
def index():
return func
res = index()
print(res)
res()
- 4.函数名还可以当做容器类型里面的数据值
def func():
print('from func')
l1 = [1,2,3,4,func]
print(l1)
l1[-1]()
- 5.构造代码流程
def register():
print('注册功能')
def login():
print('登录功能')
def check_account():
print('查看账户余额')
def withdraw():
print('体现功能')
def shopping():
print('购物功能')
def transfer():
print('转账功能')
# 提前构造功能字典
func_dict = {'1': register,
'2': login,
'3': check_account,
'4': withdraw,
'5': shopping,
'6': transfer
}
while True:
print("""
1.注册功能
2.登录功能
3.查看余额
4.提现功能
5.购物功能
6.转账功能
""")
choice = input('>>>:').strip()
if choice in func_dict:
func_name = func_dict.get(choice)
func_name()
else:
print('没有该功能编号')
今日作业
用文件实现不了全部功能
# 编写员工管理系统
# 1.添加员工信息
# 2.修改员工薪资
# 3.查看指定员工
# 4.查看所有员工
# 5.删除员工数据
# 提示:用户数据有编号、姓名、年龄、岗位、薪资
# 储存到 userinfo.txt
# 数据格式采用字典:思考如何精准定位具体数据>>>:用户编号的作用
def register():
"""
用于添加员工的基本信息
编号、姓名、年龄、岗位、薪资
然后存储到文件userinfo。txt中
:return:
"""
# 1.获取员工的编号
uid = input('请输入员工的编号:').strip()
# 2.判断当前用户是否存在
with open(r' userinfo.txt', 'r', encoding='utf8') as f:
for line in f:
real_uid = line.split('|')[0] # 拆分出员工编号
if uid == real_uid: # 进行比对
print('该员工编号已存在')
break
else:
name = input('请输入员工姓名:').strip()
age = input('请输入员工年龄:').strip()
post = input('请输入该员工的岗位:').strip()
pay = input('请输入该员工的薪资:').strip()
# 构造员工信息数据
user_data = '%s|%s|%s|%s|%s\n' % (uid, name, age, post, pay)
# 写入文件
with open(r' userinfo.txt', 'a', encoding='utf8') as f:
f.write(user_data)
print('填写完毕')
return True
def salary():
"""
读取文件修改选定员工的薪资并保持
:return:
"""
import os
uid = input('请输入员工的职工号:').strip()
# 读取文件内容
with open(r' userinfo.txt', 'rt', encoding='utf8') as f,\
open(' userinfo.txt.swap','wt',encoding='utf8') as wrife_f:
for line in f:
real_uid = line.split('|')[0] # 拆分员工编号
if real_uid == uid: # 对比员工编号
money = input('请输入更改的薪资:').strip()
pay = line.split('|')[4]
new_line = line.replace(pay,money) # 修改薪资
wrife_f.write(new_line) # 修改信息
os.remove(' userinfo.txt')
os.rename(' userinfo.txt.swap', ' userinfo.txt')
def view():
"""
读取文件内容
查看指定员工信息
:return:
"""
uid = input('请输入员工的职工号:').strip()
# 读取文件内容
with open(r' userinfo.txt', 'rt', encoding='utf8') as f:
for line in f:
real_uid = line.split('|')[0]
if real_uid == uid:
print(line)
else:
print('该职工号不存在')
return True
def all_view():
"""
读取文件内容
查找所有员工信息
:return:
"""
with open(r' userinfo.txt', 'rt', encoding='utf8') as f:
print(f.read())
return True
def delete():
"""
查看文件内容
读取该职工数据
删除该员工信息
:return:
"""
uid = input('请输入员工的职工号:').strip()
# 读取文件内容
with open(r' userinfo.txt', 'rt', encoding='utf8') as f:
for line in f:
real_uid = line.split('|')[0]
if real_uid == uid:
del line
print('该职工已删除')
else:
print('未找到该职工编号')
return True
dict = {
'1': register,
'2': salary,
'3': view,
'4': all_view,
'5': delete
}
while True:
print("""
1.添加员工信息
2.修改员工薪资
3.查看指定员工
4.查看所有员工
5.删除员工数据
""")
choice = input('请输入所需实现的功能:').strip()
if choice in dict:
func = dict.get(choice)
func()
else:
print('没有该功能')

浙公网安备 33010602011771号