python-函数(2)

内容概览

  • *与**在实参中的作用
  • 命名关键字参数
  • 名称空间
  • global与nonlocal
  • 函数名的多种使用方式

*与**在实参中的作用

"""在形参中,*与**的作用是接收多余的位置实参和关键字实参
在实参中,*与**的作用则是将容器数据类型里的数据拆分开,一次性当做参数传入
"""
# *代表将多个参数当做位置实参传入
def fn(*args, **kwargs):
	print(args, kwargs)
l1 = [1, 2, 3, 4, 5]
fn(*l1)  # (1, 2, 3, 4, 5) {}

s1 = 'hello word'
fn(*s1)  # ('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'd') {}

d1 = {'name': 'duke', 'age': 20}
fn(*d1)  # ('name', 'age') {}  

# **代表将字典里的参数当做关键字实参传入
d1 = {'name': 'duke', 'age': 20}
fn(**d1)  # () {'name': 'duke', 'age': 20}

fn(**l1)  # 只能使用列表,否则报错TypeError: **后的主.fn()参数必须是一个映射,而不是列表

命名关键字参数

"""如果想要使实参必须传入一个关键字参数,只需要将形参写在*与**之间即可"""
def fn(a, b, *args, c, **kwargs):
	print(a, b, args, c, kwargs)

fn(1, 2, 3, 4, 5)  # "Fn()缺少1个关键字参数:'c'"  此时,除了1和2传入了a和b,剩下的都被*args接收了,c想要获得参数就必须使用关键字参数
fn(1, 2, 3, 4, c=5)  # 1 2 (3, 4) 5 {}

def fn1(a, b, *args, **kwargs, c):
	pass

fn1(1, 2, 3, 4, c=5)  # "invalid syntax" 因为多余位置实参会被*args接收,多余关键字实参会被**kwargs接收,所以无论如何c都接收不到参数了,所以会报错无效语法

名称空间

用于存放变量名和变量名与数据值绑定关系的的地方

  • 名称空间的分类

    内置名称空间:在python解释器运行时就会创建的空间,写代码时可以直接使用的名字都存放在这里,在关闭python解释器时才会关闭该空间
    全局名称空间:在运行代码时创建的空间,运行过程中产生的名字(变量名、函数名、类名等)都存放在这里,在结束运行时才会关闭该空间
    局部名称空间:在调用函数时创建的空间,运行函数过程中产生的名字都会存放在这里,在函数体代码运行结束就会关闭该空间
  • 名字的查找顺序

    查找名字默认是从当前空间,由内而外一层层往外找
    当在全局名称空间时:先找全局名称空间,再找内置名称空间;都找不到则报错
    当在局部名称空间时:先找局部名称空间,再找全局名称空间,最后找内置名称空间;都找不到则报错
  • 名称空间的作用域

    内置名称空间:在任意程序任意位置都能使用
    全局名称空间:在当前程序任意位置都能使用
    局部名称空间:在各自的局部空间下使用
  • 局部名称空间的复杂情况

    • 各自局部名称空间默认不能共享名字
      def fn1():
      	s1 = 1
      	print(s2)
      
      def fn2():
      	s2 = 2
      	print(s1)
      
      fn1()
      fn2()
      """默认不能调用不同的局部名称空间名字"""
      
    • 函数嵌套

      s1 = 1
      def fn1():
      	s1 = 2
      	def fn2():
      		# s1 = 3
      		def fn3():
      			# s1 = 4
      			print(s1)  # 2 在局部名称空间中,先找当前空间,找不到再找上层空间
      		fn3()
      	fn2()
      fn1()
      
    • 特殊情况

      s1 = 1
      def fn():
      	print(s1)  # UnboundLocalError: 在赋值前引用局部变量's1'
      	s1 = 2
      
      fn()
      """其实在python执行函数语法检测的时候,检测到函数内有指定变量,就不会再往上一层名称空间查找了,而引用变量又在赋值变量前,所以会报错"""
      

global与nonlocal

"""global能够直接调用全局作用域下指定的名字"""
num = 10
def fn():
	num = 100

fn()
print(num)  # 10,正常情况下,对于不可变类型数据,在局部作用域中不能直接改变绑定的数据值

def fn1():
	global num
	num = 100

fn1()
print(num)  # 100,使用global,将全局作用域下的num引入当前局部作用域,就可以修改绑定的数据值了
"""但可变类型可以直接改变自身,不会修改绑定的地址,所以不需要使用global"""


"""nonlocal会调用上一层作用域指定的名字"""
num = 1
def fn():
	num = 10
	def fn1():
		# global num
		# print(num)  # 1,这里就不能使用global,会直接调用到全局作用域下的num
		nonlocal num
		print(num)  # 10,使用nonlocal只会往上一层找名字
		
	fn1()
fn()

函数名的多种使用方式

def fn():
	print('fn函数体代码')

# 可以使用赋值符号
res = fn  # 不能加上括号,加上括号表示调用函数体代码
res()  # fn函数体代码

# 可以当做参数传入
def fn1(f):
	f()  # fn函数体代码

fn1(fn)

# 可以当做返回值
def fn2():
	return fn

res = fn2()
res()  # fn函数体代码

# 可以当做容器类型里的一个数据值
l1 = [1, 2, 3, 4, fn]
l1[4]()  # fn函数体代码

练习

"""
编写员工管理系统
1.添加员工信息
2.修改员工薪资
3.查看指定员工
4.查看所有员工
5.删除员工数据
 提示:用户数据有编号、姓名、年龄、岗位、薪资
"""

user_info = {
    '1': {'name': 'a', 'age': '1', 'job': 'a', 'pay': '1'},
    '2': {'name': 'b', 'age': '2', 'job': 'b', 'pay': '2'}
     }


def add_user():
    """
    添加新员工
    :return:
    """
    num = input('输入员工编号:').strip()
    if num in user_info:
        print('该编号已被使用')
        return
    name = input('输入员工姓名:').strip()
    age = input('输入员工年龄:').strip()
    job = input('输入员工岗位:').strip()
    pay = input('输入员工薪资:').strip()
    user_info[num] = {'name': name, 'age': age, 'job': job, 'pay': pay}


def alter_pay():
    """
    修改指定员工薪资
    :return:
    """
    number = input('输入需要修改薪资的员工编号:').strip()
    if number not in user_info:
        print('该用户不存在')
        return
    set_pay = input(f'员工【{user_info[number]["name"]}】目前薪资为【{user_info[number]["pay"]}】,需要修改为:').strip()
    user_info[number]['pay'] = set_pay
    print(f'员工{user_info[number]["name"]}的薪水已修改为{set_pay}')


def check_user():
    """
    查看指定员工
    :return:
    """
    number = input('输入需要查看的员工编号').strip()
    if number not in user_info:
        print('该用户不存在')
        return
    user = user_info[number]
    print(f"""
    -----------------------
    编号:{number}
    姓名:{user['name']}
    年龄:{user['age']}
    岗位:{user['job']}
    薪资:{user['pay']}
    -----------------------
    """)


def check_all_user():
    """
    查看全部员工
    :return:
    """
    if not len(user_info):
        print('系统中没有员工数据')
        return
    for k, v in user_info.items():
        print(f"""  
        --------------------------------------------------
        编号:{k}    姓名:{v['name']}    年龄:{v['age']}   岗位:{v['job']}   薪资:{v['pay']}
        --------------------------------------------------""")


def del_user():
    """
    删除指定员工
    :return:
    """
    number = input('输入需要删除的员工编号:').strip()
    if number not in user_info:
        print('该用户不存在')
        return
    del_ensure = input(f'是否删除用户【{user_info[number]["name"]}】(y/n):').strip().lower()
    if del_ensure == 'y':
        user = user_info.pop(number)
        print(f'员工【{user["name"]}】已删除')

        return
    print('取消删除')


def exit_system():
    """
    退出员工信息系统
    :return:
    """
    global true
    true = 0
    print('\n成功退出系统,欢迎下次使用')


function_dict = {'1': add_user, '2': alter_pay, '3': check_user, '4': check_all_user, '5': del_user, '6': exit_system}
true = 1
while true:
    choice = input("""
    ------------------------------
            1. 添加员工信息
            2. 修改员工薪资
            3. 查看指定员工
            4. 查看所有员工
            5. 删除员工数据
            6. 退出管理系统
    ------------------------------
            请选择您要使用的功能:""").strip()
    if choice in function_dict:
        function_dict[choice]()
    else:
        print('请输入正确的编号')
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值