python函数以及名称空间与作用域
函数参数补充
*与**在实参中的作用
*号在实参中,会将*号后面的数据类型,用for循环的方式依次进行取值,并传输给函数使用,数据类型可以是列表、字符串、字典、元组,
其中字典在取值的时候,只有键会参与,值不参与
**只针对字典,它会将字典的键值对取出来,当成关键字参数的形式传输给函数
def function(*args, **kwargs):
print(args)
print(kwargs)
function() # () {}
function([11, 22, 33, 44, 55]) # ([11, 22, 33, 44, 55],) {}
l1 = [66, 77, 88, 99, 123]
function(l1[0], l1[1], l1[2], l1[3], l1[4]) # (66, 77, 88, 99, 123) {}
function(*l1) # (66, 77, 88, 99, 123) {}
s1 = 'good job'
function(*s1) # ('g', 'o', 'o', 'd', ' ', 'j', 'o', 'b') {}
dict1 = {'1': '张三', '2': '30'}
function(*dict1) # ('1', '2') {}
dict2 = {'username': '李四', 'pwd': 666}
function(**dict2) # () {'username': '李四', 'pwd': 666}
function(username='李四', pwd=666) # () {'username': '李四', 'pwd': 666}
命名关键字参数
命名关键字参数需要放在形参*args的后面,形参**kwargs的前面,不然就会报错
def function(x, y, *args, z):
print(x, y, args, z)
function(11, 22, 33, 44, 55, 66) # 报错:TypeError: function() missing 1 required keyword-only argument: 'z'
function(11, 22, 33, 44, 55, z=666) # 11 22 (33, 44, 55) 666
def function(x, y, *args, z, **kwargs):
print(x, y, args, z, kwargs)
function(11, 22, 33, 44, 55, z=777, name='张三', age=888) # 11 22 (33, 44, 55) 777 {'name': '张三', 'age': 888}
名称空间与作用域
名称空间
名称空间就是用来存放变量名与数据值之间绑定关系的地方
username = '张三'
首先在内存中申请一块内存空间用于存储数据值张三,然后绑定给变量名username
变量名username与数据值张三的绑定关系就会存储到名称空间里,后续如果需要使用变量名都是去名称空间里查找并锁定对应的数据值
del username 删除的不是数据值,而是变量名以及变量名与数据值之间绑定的关系
username = '张三'
print(username)
print(username)
print(username)
del username
print(username) # NameError: name 'username' is not defined
名称空间的分类
内置名称空间
python解释器运行就会创建的名称空间,写代码过程中可以直接使用的名字都在该空间内。eg: len() print() input()…..
全局名称空间
py文件运行代码过程中产生的名字都会存入该名称空间,如逻辑代码的变量名,分支结构的变量名,循环结构的变量名,以及定义函数的函数名
局部名称空间
函数体代码运行过程中产生的名字都会存入该名称空间
名字的查找顺序
查找名字之前一定要先看自己在哪个名称空间
1.当前在全局名称空间
全局名称空间 >>>: 内置名称空间
2.当前在局部名称空间
局部名称空间 >>>: 全局名称空间 >>>: 内置名称空间
名字的查找顺序默认情况下不能颠倒只能是 局部>>>:全局>>>:内置
名字的存活周期
存活周期
1.内置名称空间
python解释器运行 产生
python解释器关闭 销毁
2.全局名称空间
py文件开始运行 产生
py文件运行结束 销毁
3.局部名称空间
函数体代码开始运行 产生
函数体代码运行结束 销毁
作用域
1.内置名称空间
在程序任意位置都可以使用(全局有效)
2.全局名称空间
在程序任意位置都可以使用(全局有效)
3.局部名称空间
在各自的局部空间可以使用(局部有效)
global与nonlocal关键字
gloabl关键字:局部修改全局不可变类型
# x = 111
# def index():
# # x = 222 # 并不是在修改全局的x 而是在局部名称空间中创建了一个新的x
# # 如果想要在局部名称空间中修改全局名称空间中的名字 那么需要使用关键字申明
# global x # 修改的是全局x而不是产生新的x
# x = 666
# index()
# print(x)
l1 = [111, 222, 333]
def index():
l1.append(444)
index()
print(l1)
"""
如果想要在局部修改全局的不可变类型
需要提前加关键字global申明
如果想要在局部修改全局的可变类型
不需要加关键字global申明
"""
def index():
x = 111 # 在index的局部产生一个x=111
l1 = [11, 22, 33]
def f1():
# x = 222 # 在f1的局部产生一个x=222
# print(x)
# 局部名称空间嵌套 内层修改外层
# nonlocal x
# x = 333
l1.append(44)
f1()
print(x)
print(l1)
index()
局部名称空间嵌套的情况下 内层如果想要修改外层
情况1数据是不可变类型
需要使用关键字nonlocal
情况2数据是可变类型
不需要使用关键字nonlocal
局部名称空间的复杂情况
x = 111
如果函数没有被调用 那么不要去管函数体代码有多复杂,先跳过
def f1():
x = 222
def f2():
x = 333
def f3():
print(x) # 检测语法的时候 发现f3的局部名称空间将来会有x 所以查找的时候就跟f3的局部名称空间要(特例 可以忽略)
x = 444
# print(x)
f3()
f2()
f1()
局部名称空间之间如果不是嵌套关系 那么互不干涉!!!
def index1():
name = 'jason'
def index2():
age = 18
print(name) # 报错
index1()
index2()
函数名的多种使用方式
# def index():
# print('from function index')
# 用法1:函数名可以当做变量名赋值
# print(index)
# res = index # 让res也指向函数体代码
# print(res)
# res() # index()
# 用法2:函数名还可以当成函数的实参
# def index():
# print('from index')
# def func(a):
# print('from func')
# print(a)
# a()
# func(index)
# 用法3:函数名还可以当做函数的返回值
# def func():
# print('from func')
# return index # 将函数名当做返回值
# def index():
# print('from index')
# res = func() # res接收函数名
# print(res) # 指向的是index函数的内存地址
# res() # index()
# 用法4:函数名可以作为容器类型的元素
'''容器类型:内部可以存放多个元素的数据类型>>>:列表、元组、字典'''
# def index():
# print('from index')
# l1 = [11, 22, 33, 44, index]
# print(l1)
# l1[-1]() # index()
课题演练
# 使用函数封装完成员工管理系统
# 1.添加员工信息
# 2.修改员工薪资
# 3.查看指定员工
# 4.查看所有员工
# 5.删除员工数据
# 提示:用户数据有编号、姓名、年龄、岗位、薪资
# 1.构造主体功能
def register():
print('员工注册登录功能')
emp_id = input('请输入员工的编号>>>:').strip()
# 1.判断该员工编号是否已经存在
if emp_id in data_dict:
print('该员工编号已存在')
# 2.获取员工的其他信息
user_name = input('请输入员工姓名>>>:').strip()
user_age = input('请输入员工年龄>>>:').strip()
user_job = input('请输入员工岗位>>>:').strip()
user_salary = input('请输入员工薪资>>>>:').strip()
# 3.创建一个存放员工数据的小字典
user_info = {}
# 4.将员工信息全部放入小字典
user_info['emp_id'] = emp_id
user_info['user_name'] = user_name
user_info['user_age'] = user_age
user_info['user_job'] = user_job
user_info['user_salary'] = user_salary
# 5.将员工数据小字典放入大字典里
data_dict[emp_id] = user_info
def change():
print('员工信息修改功能')
# 1.获取员工编号
emp_id = input('请输入员工编号>>>:').strip()
# 2.判断当前员工编号是否存在
if emp_id not in data_dict:
print('当前员工不存在,无法进行修改')
# 3.根据员工编号获取员工的详细信息
emp_data = data_dict.get(emp_id)
# 4.获取该员工新的薪资
new_salary = input('请输入该员工新的薪资>>>:').strip()
# 5.修改员工小字典里对应的数据
emp_data['user_salary'] = new_salary
# 6.将修改后的小字典重新赋值给大字典
data_dict[emp_id] = emp_data
# 7.提示信息:员工薪资已修改
print(f'员工编号:{emp_id}, 员工姓名:{emp_data.get("user_name")}薪资修改成功')
def look():
print('查看员工信息功能')
# 1.获取所有的员工小字典
all_emp_data = data_dict.values()
# 2.循环获取每一个员工数据字典
for emp_data in all_emp_data:
# 3.格式化输出员工信息
print(f"""
---------------emp_info---------------
编号:{emp_data.get('emp_id')}
姓名:{emp_data.get('user_name')}
年龄:{emp_data.get('user_age')}
岗位:{emp_data.get('user_job')}
薪资:{emp_data.get('user_salary')}
--------------------------------------
""")
def delete():
print('删除员工信息功能')
delete_id = input('请输入您想要删除的员工编号>>>:').strip()
# 2.判断该员工编号是否存在
if delete_id not in data_dict:
print('该员工编号不存在')
# 3.根据员工编号删除对应的键值对
data_dict.pop(delete_id)
# 4.提示信息
print(f'员工编号{delete_id}删除成功')
# 2.构造一个功能字典
function_dict = {'1': register, '2': change, '3': look, '4': delete}
# 3.构造一个存放员工数据的字典
data_dict = {}
while True:
print("""
1.注册功能
2.修改功能
3.查看功能
4.删除功能
""")
select = input('请输入您想要执行的功能编号>>>:').strip()
if select in function_dict:
function_name = function_dict.get(select)
function_name()
else:
print('该功能编号不存在')
原创文章,作者:306829225,如若转载,请注明出处:https://blog.ytso.com/tech/python/272885.html