python之函数


目录
  • 函数的分类
    • 内置函数
    • 自定义函数
  • 函数的定义与调用
    • 函数的定义
    • 函数的调用
  • 函数的返回值
  • 函数的参数(重要)
    • 位置参数
    • 关键字参数
    • 默认参数
    • 可变长参数(重要)
      • 可变长形参(*变量名)
      • 可变长形参(**变量名)
      • 拓展
      • *与**在实参中的用处
  • 作业
  • 答案

函数的分类

函数分为两大类,内置函数和自定义函数。

内置函数

内置函数其实我们在学习数据类型的时候就已经用到了,它们是python解释器提前定义好可以直接使用的函数,像:len()、strip()、split()等等

自定义函数

自定义函数,听名字就知道这是我们可以自己定义的函数,自定义函数又可以分为三小类:无参函数、有参函数、空函数。

  1. 无参函数:定义函数时括号内没有参数
# 定义无参函数
def my_func():
    print("hello world")
# 调用无参函数
my_func()  # 输出:hello world

"""定义时括号内没有参数,则调用时也不能有参数"""
  1. 有参函数:定义函数时括号内有参数
# 定义有参函数
def my_func(a):
    print(a)
# 调用有参函数
my_func("hello world")  # 输出:hello world

"""定义时括号内有几个参数,调用时就要给几个参数"""
  1. 空函数:定义函数时函数体代码用pass或...带过
# 定义空函数
def my_func():
    pass

"""
空函数主要用于快速的罗列出程序的大概功能,让整体框架清晰起来
比如我要用函数实现登录注册功能
我可以先定义用于实现注册的空函数和实现登录的空函数
写完主体代码之后再去编写函数内的具体内容
"""

函数的定义与调用

函数的定义

函数的定义已经在上一个博客中讲解过了,这里只做一个展示。

def 函数名(参数1, 参数2, ...):
    """函数描述"""
    函数体代码
    return 返回值

函数的调用

知道了函数如何定义,自然还要知道函数该如何调用。

调用函数其实非常简单,直接用函数名加括号就可以了,就像使用print()一样。

# 函数的定义
def my_function():
    print("hello world")

# 函数的调用
my_function()  # 输出:hello world

注意事项:

  1. 函数的定义一定要在函数的调用前面,要想定义,后调用。
# 如果先调用,后定义,像这样:

# 函数的调用
my_function()

# 函数的定义
def my_function():
    print("hello world")
    
"""报错:NameError: name 'my_function' is not defined"""
  1. 函数体代码只有在调用函数的时候才会执行,所以函数体代码里如果有错误并不会第一时间提醒你。

函数的返回值

函数的返回值就是在调用函数时,函数给你的结果。

比如:

s = 'hello'
result = len(s)  # 这里就是len()函数将它的返回值赋值给了result

有上述例子可以看出,我们只需要将变量名=函数调用,就可以获取函数的返回值了。

在了解了如何获取返回值后,自然要知道如何自己定义返回值。

# 当函数没有return关键字或者没有return任何数据时,返回值为None
def my_func1():
    pass

def my_func2():
    return

result = my_func1()
print(result)  # 输出:None

result = my_func2()
print(result)  # 输出:None

# 当函数内有return关键字且后面跟了数据的,那么后面跟的是什么数据返回的就是什么

# return后跟一个值,直接返回跟的返回值
def my_func1():
    return 'hello'
result = my_func1()
print(result)  # 输出:hello

# return后跟多个值,返回的值会合成元组后返回
def my_func2():
    return 'hello', 123, [1, 2]
result = my_func2()
print(result)  # 输出:('hello', 123, [1, 2])

注意事项:函数遇到return关键字会立刻退出函数,就像while和for循环里遇到了break一样

函数的参数(重要)

函数的参数可以分为两大类:

  1. 形参:形式参数,函数在定义阶段括号内所写的参数,在函数调用时会被取代的参数。
  2. 实参:实际参数,函数在调用阶段括号内所写的参数,用于取代形参进入函数。
def my_func(a, b):
    pass
my_func(1, 2)

"""
在上述例子中,a和b就是形参,1和2就是实参
在调用函数时,1和2会临时取代a和b,函数内代码执行完后,1和2就会离开a和b,这是a和b就会等待下一次函数调用
"""

位置参数

在函数的调用过程中,括号内传入的实参必须与定义函数括号内的形参一一对应,从左往右挨个绑定。

def my_func(a, b):
	print(a, b)
my_func('tom', 123)  # 输出:tom 123
my_func(123, 'tom')  # 输出:123 tom
my_func(123)  # 报错
my_func(123, 45, 7)  # 报错
my_func()  # 报错

主要注意两点:

  1. 按顺序传参,不然会乱
  2. 传参不能多也不能少,要刚刚好

关键字参数

在给函数传参过程中我们可以指定给形参传值。

def my_func(a, b, c):
	print(a, b, c)
my_func(b=123,c='jason', a='tom')  # 输出:tom 123 jason
my_func(123, b='tom', c='jason')  # 输出:123 tom jason  相当于位置参数
my_func(123, b='jason', 'tom')  # 报错  关键字传值必须要在位置参数的后面
my_func(123, 'jason', b='tom')  # 报错  不能重复传值

主要注意两点:

  1. 关键字参数必须要在位置参数的后面
  2. 不能重复传值

默认参数

如果在函数定义阶段时,就已经给形参赋值了,那我们称这个为默认参数。

调用函数时如果不传值则会使用定义阶段赋给它的值,传值的话就是使用传的值。

默认参数的出现也打破了形参与实参之间个数一致的情况。

# 默认参数在定义是必须要放在位置参数后面
def my_func(a, b, c=123):
    print(a, b, c)
my_func('tom', 'jason')  # 输出:tom jason 123
my_func('tom', 'jason', 456)  # 输出:tom jason 456

主要注意两点:

  1. 定义函数时默认参数必须要放在位置参数后面
  2. 不传参数用默认,传了参数用传的

可变长参数(重要)

如果此时有一串数据要传入函数,不知道有多少个,那么应该如何定义函数呢?

这个时候就需要用到可变长形参了,它可以接收数个参数。

可变长形参(*变量名)

可以接受多余的位置参数,并将多余参数转换成元组类型赋值给*后面的变量名。

def my_func(a, b, *c):  # *c就是可变长形参
    print(a, b, c)
my_func(1, 2)  # 输出:1 2 ()
my_func(1, 2, 3, 4, 5)  # 输出:1 2 (3, 4, 5)
my_func(1)  # 报错  位置参数只能多,不能少

主要注意两点:

  1. 位置参数只能多,不能少
  2. 定义可变长形参时如果放在位置参数前面,那么后面的位置参数需要用关键字传参

可变长形参(**变量名)

可以接受多余的关键字参数,并将多余参数转换成字典类型赋值给**后面的变量名。

def my_func(a, b, **c):  # **c就是可变长形参
    print(a, b, c)
my_func(1, 2)  # 输出:1 2 {}
my_func(1, 2, c=3, d=4, e=5)  # 输出:1 2 {'d': 3, 'e': 4, 'f': 5}
my_func(1)  # 报错  位置参数b没有拿到值
my_func(1, 2, 3)  # 报错  多余的参数必须要用关键字传参

主要注意两点:

  1. 位置参数要对应
  2. 多余的参数必须要用关键字传参

拓展

如何定义一个无论接收多少个任意类型的参数都可以正常执行的函数?

# 可以传入数个任意类型参数
def my_func(*args, **kwargs):
    print(args, kwargs)
    
"""小补充:针对这*和**后面的变量名,我们推荐都这么写:*args和**kwargs"""

*与**在实参中的用处

*与**不仅可以在形参中使用,还能在实参中使用。

def my_func(*args, **kwargs):
    print(args, kwargs)

# *的使用,可以将列表或者元组打散成位置参数一一传入
my_func(*[5, 6, 7, 'tom'])  # 等价于my_func(5, 6, 7, 'tom')
my_func(*(5, 6, 7, 'tom'))  # 等价于my_func(5, 6, 7, 'tom')
"""*里面不能有字典类型,不然会报错"""

# **的使用,可以将字典打散成关键字参数一一传入
my_func(**{'a':1, 'b':2})  # 等价于my_func(a=1, b=2)

作业

用函数实现员工信息管理

答案

点击查看代码
# user_info = []
user_info = [
    {"id": 1, "name": "abc1", "age": 18, "salary": 8888},
    {"id": 2, "name": "abc2", "age": 18, "salary": 8888},
    {"id": 3, "name": "abc3", "age": 18, "salary": 8888},
]
# 用于id自增
user_id = 3


# 初始化
def init():
    print("功能列表".center(30, '*'))
    print("1.添加员工信息".center(30, '-'))
    print("2.查询员工信息".center(30, '-'))
    print("3.查看全部员工".center(30, '-'))
    print("4.修改员工薪资".center(30, '-'))
    print("5.删除员工信息".center(30, '-'))
    print("6.退出员工系统".center(30, '-'))
    print("".center(33, '—'))


# 添加员工
def add_user(username, age, salary):
    global user_id

    # 判断用户名是否已存在,并且用户名是否为纯数字
    for user_dict in user_info:
        if user_dict['name'] == username:
            print('用户已存在!请重新输入....'.center(30, '-'))
            return False
    else:
        if username.isdigit():
            print('用户名不能为纯数字!请重新输入....'.center(30, '-'))
            return False
        elif username == "":
            print('用户名不能为空!请重新输入....'.center(30, '-'))
            return False

    # 判断年龄是否是纯数字
    if age.isdigit():
        real_age = int(age)
    else:
        print("年龄输入错误!请重新输入....".center(30, '-'))
        return False

    # 判断薪资是否是纯数字 不是的话就一直让用户输入
    if salary.isdigit():
        real_salary = int(salary)
    else:
        print("薪资输入错误!请重新输入....".center(30, '-'))
        return False

    # 录入系统,并提示用户
    temp_dict = {}
    user_id += 1
    temp_dict['id'] = user_id
    temp_dict['name'] = name
    temp_dict['age'] = age
    temp_dict['salary'] = salary
    user_info.append(temp_dict)
    print('用户:%s添加成功' % name)
    return True


# 查找员工
def select_user(name_or_id):
    # 判断输入的是否是纯数字,如果是说明输入的是编号,反之则是姓名
    if name_or_id.isdigit():
        id = int(name_or_id)
        for user in user_info:
            if user['id'] == id:
                print(f"编号:{user['id']},姓名:{user['name']},年龄:{user['age']},薪资:{user['salary']}")
                return True
        else:
            print("你输入的编号不存在!".center(30, '-'))
            return False
    else:
        for user in user_info:
            if user['name'] == name_or_id:
                print(f"编号:{user['id']},姓名:{user['name']},年龄:{user['age']},薪资:{user['salary']}")
                return True
        else:
            print("你输入的用户名不存在!".center(30, '-'))
            return False


# 查找全部员工
def select_all():
    if user_info == []:
        print("系统内没有员工!".center(30, '-'))
        return False
    for user_dic in user_info:
        print(f"编号:{user_dic['id']},姓名:{user_dic['name']},年龄:{user_dic['age']},薪资:{user_dic['salary']}")
    return True


# 修改薪资
def change_salary(name_or_id, salary):
    # 判断输入的是否是纯数字,如果是说明输入的是编号,反之则是姓名
    if name_or_id.isdigit():
        id = int(name_or_id)
        for user in user_info:
            if user['id'] == id:
                # 判断薪资是否是纯数字
                if salary.isdigit():
                    real_salary = int(salary)
                    user['salary'] = real_salary
                    print(f"员工{user['name']}的薪资修改成功!".center(30, '-'))
                    return True
                else:
                    print("薪资输入错误!请重新输入....".center(30, '-'))
                    return False
        else:
            print("你输入的编号不存在!请重新输入....".center(30, '-'))
            return False
    else:
        for user in user_info:
            if user['name'] == name_or_id:
                # 判断薪资是否是纯数字
                if salary.isdigit():
                    real_salary = int(salary)
                    user['salary'] = real_salary
                    print(f"员工{user['name']}的薪资修改成功!".center(30, '-'))
                    return True
                else:
                    print("薪资输入错误!请重新输入....".center(30, '-'))
                    return False
        else:
            print("你输入的用户名不存在!请重新输入....".center(30, '-'))
            return False


# 删除员工
def delect_user(name_or_id):
    # 判断输入的是否是纯数字,如果是说明输入的是编号,反之则是姓名
    if name_or_id.isdigit():
        id = int(name_or_id)
        for user in user_info:
            if user['id'] == id:
                while True:
                    confirm_cmd = input(f"确定是否删除编号为{id}的员工(y/n)?")
                    if confirm_cmd == 'y':
                        user_info.remove(user)
                        print(f"已删除编号为{id}的员工".center(30, '-'))
                        break
                    elif confirm_cmd == 'n':
                        print("已退回初始菜单".center(30, '-'))
                        break
                    else:
                        print("请勿输入y或n以外的命令!".center(30, '-'))
                return True
        else:
            print("你输入的编号不存在!请重新输入....".center(30, '-'))
            return False
    else:
        for user in user_info:
            if user['name'] == name_or_id:
                while True:
                    confirm_cmd = input(f"确定是否删除姓名为{name_or_id}的员工(y/n)?")
                    if confirm_cmd == 'y':
                        user_info.remove(user)
                        print(f"已删除编号为{name_or_id}的员工".center(30, '-'))
                        break
                    elif confirm_cmd == 'n':
                        print("已退回初始菜单".center(30, '-'))
                        break
                    else:
                        print("请勿输入y或n以外的命令!".center(30, '-'))
                return True
        else:
            print("你输入的用户名不存在!请重新输入....".center(30, '-'))
            return False


init()
while True:

    choice = input('请输入你想要执行的功能>>>:')

    if choice == '1':
        # 1.添加员工信息
        while True:
            name = input('请输入您的用户名>>>:').strip()
            age = input('请输入您的年龄>>>:').strip()
            salary = input('请输入您的薪资>>>:').strip()
            if add_user(name, age, salary):
                break

    elif choice == '2':
        # 2.查询员工信息
        while True:
            user_input = input('请输入需要查询的员工编号或姓名>>>:').strip()
            if select_user(user_input):
                break

    elif choice == '3':
        # 3.查询全部员工
        select_all()

    elif choice == '4':
        # 4.修改员工薪资
        while True:
            name_or_id = input('请输入需要修改的员工编号或姓名>>>:').strip()
            salary = input('请输入员工现在的薪资>>>:').strip()
            if change_salary(name_or_id, salary):
                break

    elif choice == '5':
        # 5.删除员工信息
        while True:
            user_input = input('请输入需要删除的员工编号或姓名>>>:').strip()
            if delect_user(user_input):
                break

    elif choice == '6':
        # 6.退出员工系统
        print("拜拜了您嘞!".center(30, '-'))
        break

    else:
        print('请输入正确指令'.center(30, '-'))