函数-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号
浙公网安备 33010602011771号