可变长参数在形参和实参的作用、命名关键字参数、名称空间、函数名的多种使用方式、练习

可变长参数在实参、形参中的作用

1.可变长参数在形参的作用
  *作用:*用来接收实参中多余的位置参数,并组织以元组的形式传递给*号后面的args变量名
  **作用:**用来接收形参中多余的关键字参数,并组织以字典的形式传递给**号后面的kwargs变量名
	ps:
    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    func()  # () {}
    func(1,2,3)  # (1, 2, 3) {}
    func([1,2,3],name= 'nana',kw = 123)  # ([1, 2, 3],) {'name': 'nana', 'kw': 123}
2.可变长参数在实参的作用
  *作用:类似于for循环一次性拿到容器类型里的数据值,再传递给位置形参中
  **作用:把字典的键值对以关键字参数的形式传递给关键字参数中
	ps:
    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    l1 =[1,2,3,4]
    func(*l1)  # (1, 2, 3, 4) {}
    func(*l1,**l1)  # 报错 func() argument after ** must be a mapping, not list
    s1 = 'xiao'
    func(*s1)  # ('x', 'i', 'a', 'o') {}
    func(*l1,*s1)  # (1, 2, 3, 4, 'x', 'i', 'a', 'o') {}
    func(*s1,name= 'nana',kw = 123)  # ('x', 'i', 'a', 'o')  {'name': 'nana', 'kw': 123}
    dic1 ={'name':'xiao','age':18}
    func(*dic1)  # ('name', 'age') {}

    dic1 ={'name':'xiao','age':18}
    func(**dic1) # () {'name': 'xiao', 'age': 18}
    func(*l1,**dic1)  # (1, 2, 3, 4)  {'name': 'xiao', 'age': 18}

命名关键字参数

需要形参在传参的时候,按照关键字参数,此时用到命名关键字参数
1.关键字参数必须在形参*args的后面
  eg:
  def func(a,b,*args,c):
      print(a,b,c,args)
  func(6,4,5,c=3) # 6 4 3 (5,)  
2.关键字参数必须在**kwargs前面
  eg:
  def func(a,b,*args,c,**kwargs):
      print(a,b,args,c,kwargs)
  func(6,4,5,c=3,d=6,name='nana') # 6 4 (5,) 3 {'d': 6, 'name': 'nana'}

名称空间

名称空间介绍

1.名称空间就是用来存放变量名与数据值之间绑定关系的地方
2.举例说明:
  2.1 name = 'nana'
      在内存中申请一块内存空间存储nana 然后绑定变量名name
      变量名name与数据值nana的绑定关系就会被存储到名称空间中,之后使用名字都是去名称空间中查找并锁定对应的值
  2.2 del name
	  删除的不是数据值,而是变量名name以及变量名name与数据值nana之间的绑定关系
  

名称空间的分类

名称空间分为内置名称空间、全局名称空间、局部名称空间

1.内置名称空间:python解释器运行立刻就会创建的名称空间
			 写代码的过程中可以直接使用的名字都在内置名称空间中
    		 eg:print()、 len()
2.全局名称空间:py文件运行代码的过程产生的名字都会存入到该空间
               包含普通代码里产生的变量名、分支、循环结构里产生的变量名、定义函数产生的函数名、定义类产生的类名
3.局部名称空间:函数体代码运行的过程中产生的名字都会存入到该局部名称空间
	eg:
	x=1     
	l1 = [1,2,3]
	if x == 2:
    	name = 'nana'
	for i in l1:
    	print(i)
	def func():
    	age = 19
	func()   
     全局名称空间:x=1、l1 = [1,2,3]、name = 'nana'、i、func()
	局部名称空间;age = 19

名称空间的存活周期

1.内置名称空间:解释器运行就创建,解释器关闭就销毁
2.全局名称空间:py文件运行就创建,py文件关闭就销毁
3.局部名称空间:函数体代码运行就创建,函数体diamante结束就销毁

名称空间的名字查找顺序

1.首先在查找名称空间之前,应先确定当前在那一块名称空间
2.分情况查找
	2.1 当前在全局名称空间,如果全局空间没有,就去内置名称空间查找
    	eg:
		s1 ='nana'
        print(len(s1))  # 4

        s1 ='nana'
        len = '全局里的'
        print(len)  # 全局里的	
    2.2 当前在局部名称空间,如果局部名称空间没有,就去全局名称空间查找,如果全局名称空间没有,就去内置名称空间查找
    	eg:
		name = 'nana'
        def func():
            name = 'xiao'
            print(name)  # xiao
        func()

        name = 'nana'
        def func():
            print(name)  # nana
        func()  
ps:名称空间的查找顺序默认情况下不能颠倒,只能是局部到全局到内置名称空间
    

名称空间的作用域

1.内置名称空间:在程序的任意位置都可以使用(全局有效)
2.全局名称空间:在程序的任意位置都可以使用(全局有效)
3.局部名称空间:在各自的局部空间可以使用(局部有效)
	3.1 各自局部名称空间默认情况下不能彼此共享名字
    	eg:
         def func1():
             name = 'nana'
             print(age)
         def func2():
             age = 12
             print(name)
         func1()
         func2()  # 报错
            
	3.2 特殊情况
        eg:
        x = 1
        def func1():
            x=2
            def func2():
                x=3
                def func3():
                    x=4
                    print(x)  # 4
                func3()
            func2()
        func1()
        print(x)  # 1
	3.3 函数在定义阶段其实名字的查找顺序就已经固定死了
    	eg:
        name = 'nana'
        def func():
            print(name)  # 报错local variable 'name' referenced before assignment
            name = 'xiao'
        func()

关键字:global、nonlocal

正常情况下,局部名称空间里面出现新的名字会在局部名称空间里存储,但是有时候需要在局部名称空间里面修改全局名称空间的名字或者需要在内层局部名称空间修改外层局部名称空间的名字,此时对于不可变类型数据会用到global、nonlocal

1.局部修改全局名称空间
	1.1局部名称空间修改全局名称空间的数据类型是可变类型,不需要加global关键字声明
    eg:
	l1 =[1,2,3,4]
    def func():
        global l1
        l1.append(0)
        print(l1)  # [1, 2, 3, 4, 0]
    func()
    print(l1)  # [1, 2, 3, 4, 0]


    l1 =[1,2,3,4]
    def func():
        l1.append(0)
        print(l1)  # [1, 2, 3, 4, 0]
    func()
    print(l1)  # [1, 2, 3, 4, 0]
    
    1.2局部名称空间修改全局名称空间的数据类型是不可变类型,则需要使用global关键字声明
    eg:
    x = 1
    def func():
        x = 11
    func()
    print(x)  # 1

    x = 1
    def func():
        global x
        x = 11
    func()
    print(x)  # 11
2.内层局部名称空间修改外层局部名称空间
	2.1内层局部名称空间修改外层局部名称空间的数据类型是可变类型,不需要加nonlocal关键字声明
    eg:
	def func1():
        l1 =[1,2,3]
        print(l1)  # [1, 2, 3]
        def func2():
            l1.append(999)
            print(l1)  # [1, 2, 3, 999]
        func2()
        print(l1)  # [1, 2, 3, 999]
    func1()

    def func1():
        l1 =[1,2,3]
        print(l1)  # [1, 2, 3]
        def func2():
            nonlocal l1
            l1.append(999)
            print(l1)  # [1, 2, 3, 999]
        func2()
        print(l1)  # [1, 2, 3, 999]
    func1()
    2.2 内层局部名称空间修改外层局部名称空间的数据类型是不可变类型,需要加nonlocal关键字声明
    eg:
    def func1():
    x = 1
    def func2():
        nonlocal x
        x = 999
        print(x)  # 999
    func2()
    print(x)  # 999
func1()

函数名的多种使用方式

1.函数名也可以被用来多次赋值(函数名与变量名使用一致)
	def func():
        print('from func')
    name = func
    print( name)  # <function func at 0x000001D782E91E18>
    name1 = name
	print(name1)  # <function func at 0x000001846EFC1E18>
2.函数名还可以当做参数的实参
	def func():
        print('from func')  # from func
    def index(a):
        print(a)  # <function func at 0x0000024D3B2C1E18>
        a()
    index(func)
3.函数名还可以当做海曙的返回值
	def func():
        print('from func')   # from func
    def index():
        return func
    res = index()
    res()
4.函数名还可以当做容器类型里面的数据值
	def func():
        print('from func')  # from func
    l1 = [1,2,3,4,5,func]
    l1[-1]()

项目搭建格式

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.删除员工数据
提示:用户数据有编号、姓名、年龄、岗位、薪资
数据格式采用字典:思考如何精准定位具体数据>>>:用户编号的作用

out_dict={}
def add_info():
    user_id = input("请输入你的员工编号>>>:").strip()
    if user_id in out_dict:
        print("该员工已存在")
    else:
        user_name = input("请输入你的姓名>>>:").strip()
        user_age = input("请输入你的年龄>>>:").strip()
        user_job = input("请输入你的岗位>>>:").strip()
        user_salary = input("请输入你的薪资>>>").strip()
        in_dict = {}
        in_dict['name'] = user_name
        in_dict['age'] = user_age
        in_dict['job'] = user_job
        in_dict['salary'] = user_salary
        out_dict[user_id] = in_dict
        print(f'用户{user_name}添加成功')
def change_salary():
    info_id = input("请输入你想要修改的员工的编号>>>").strip()
    if info_id not in out_dict:
        print("该员工不存在")
    else:
        info_salary = input("请输入你想要修改的金额>>>").strip()
        if info_salary.isdigit:
            out_dict[info_id]['salary'] = info_salary
            print("修改成功")
        else:
            print("请输入数字")
def check_index_staf():
    user_id = input("请输入你想查看员工编号").strip()
    if user_id not in out_dict:
        print("该员工不在")
    else:
        print(out_dict[user_id])
def check_info():
    print(out_dict)
def del_info():
    del_id = input("请输入你想要删除的员工编号").strip()
    if del_id not in out_dict:
        print('没这个人')
    else:
        del out_dict[del_id]
        print("删除成功")
func_dict = {
    '1':add_info,
    '2':change_salary,
    '3':check_index_staf,
    '4':check_info,
    '5':del_info
}
while True:
    print("""
    1.添加员工信息
    2.修改员工薪资
    3.查看指定员工
    4.查看所有员工
    5.删除员工数据
    """)
    choice = input("请输入你的指令>>>:").strip()
    if choice in func_dict:
        func_dict.get(choice)()
    else:
        print("请输入正确的指令")
posted @ 2022-07-04 17:34  DRAMA-娜娜  阅读(51)  评论(0编辑  收藏  举报