Python函数:四类参数,拆包,引用,类型可变与不可变

一、函数传参的四类参数

1、位置传参与关键字传参

# 位置传参,按照形参的位置顺序将实参的值传递给形参

# 关键字传参,指定实参给到哪个形参, 注意点: 关键字必须是函数的形参名

# 混合使用, 先写位置传参,再写关键字传参
'''先写没等号的,再写有等号的,有等号的要在后边'''

def func(a, b, c):
    print(f'a:{a}')
    print(f'b:{b}')
    print(f'c:{c}')


# 位置传参
func(1,2,3)
# func(3,1,2)
# 关键字传参
func(a=10, b=20, c=30)
# func(c=10, a=20, b=30)
# 混合使用, 先写位置传参,再写关键字传参
'''先写没等号的,再写有等号的,有等号的要在后边'''
func(10, b=20, c=30)
# func(a=10, 20, 30)  # 代码会报错
# func(10, a=30, b=20)  # 代码会报错

2、缺省参数

"""
缺省参数,形参.在函数定义的时候,给形参一个默认值,这个形参就是缺省参数,
注意点: 缺省参数要写在普通参数的后边
特点: 在函数调用的时候,如果给缺省参数传递实参值,使用的是传递的实参值,如果没有传递,使用默认值
"""

# print()

'''
有等号的在后边写
'''


def func(a, b, c=10):  # 形参c 称为缺省形参
    print(f"a: {a}")
    print(f"b: {b}")
    print(f"c: {c}")


func(1, 2)  # 没有给c 传递实参,使用默认值10
func(1, 2, 3)  # 给c传递实参值,使用传递的数据3

# def fun1(a=1, b, c):   # 代码报错,语法错误
#     pass

3、不定长参数(重点)

有两个注意点: 函数定义中的 args 和 kwargs可以是任意的形参变量,不过习惯使用 args 和 kwargs.

'''
在形参前边加上一个*, 该形参变为不定长元组形参,可以接收所有的位置实参, 类型是元组(*args)
在形参前边加上两个**, 该形参变为不定长字典形参, 可以接收所有的关键字实参,类型是字典
(**kwargs)'''
 

# print(1)
# print(1, 2)
# print(1, 2, 3)
# print(1, 2, 3, 4)
# print(1, 2, 3, 4, 5)


def func(args, kwargs):  # 两个普通的形参
    print(args)
    print(kwargs)


func(1, 2)
func(args=2, kwargs=1)

print('*' * 30)
print('*' * 30)



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


func(1, 2, 3, 3, 4, 5)
'''(1, 2, 3, 3, 4, 5)
{}'''
func(a=1, b=2, c=3, d=4)
'''()
{'a': 1, 'b': 2, 'c': 3, 'd': 4}'''
func(1, 2, 3, a=4, b=5, d=6)
'''(1, 2, 3)
{'a': 4, 'b': 5, 'd': 6}'''

 重点!!!(下面的)

def func(*args, **kwargs):
    print('args', args)
    print('kwargs', kwargs)


my_list = [1, 2, 3, 4, 5, 6]
my_dict = {'a': 7, 'c': 8, 'b': 9, 'd': 10}

func(my_list)  # 将列表作为一个数据进行传递(整体)
'''args ([1, 2, 3, 4, 5, 6],)
kwargs {}'''
func(*my_list)  # 将列表中的每一个数据作为位置参数进行传递, 拆包
'''args (1, 2, 3, 4, 5, 6)
kwargs {}'''
# func(**my_list )  # 这个会报错,因为本来该是元组的类型,加两个*号,该放在字典的位置上,有冲突!

func(my_dict)  # 将my_dict 作为一个位置实参进行传递(元组)
'''args ({'a': 7, 'c': 8, 'b': 9, 'd': 10},)
kwargs {}'''
func(*my_dict)  # 将my_dict中的key 作为位置实参进行传递(元组)
'''args ('a', 'c', 'b', 'd')
kwargs {}'''
func(**my_dict)  # 将my_dict中键值对作为关键字实参进行传递
'''args ()
kwargs {'a': 7, 'c': 8, 'b': 9, 'd': 10}'''

4、应用

def my_sum(*args, **kwargs):
    num = 0
    for i in args:
        num += i  # num = num + i

    for j in kwargs.values():
        num += j

    print(f"求和的结果为{num}")


my_sum(1, 2, 3, a=4, b=5, c=6)  # 21

5、函数参数的完整格式

#依次的顺序
普通形参  不定长元组形参  缺省形参 不定长字典形参

# 普通形参  缺省形参  不定长元组形参   不定长字典形参
def func(a, b=1):  # 先普通再 缺省
    pass


def func1(a, b=1, *args):  # 语法上不会报错,但是缺省参数不能使用默认值
    print('a', a)
    print('b', b)
    print(args)


def func2(a, *args, b=1):  # 普通形参  不定长元组形参  缺省形参
    print('a', a)
    print('b', b)
    print(args)


def func3(a, *args, b=1, **kwargs):  # 普通形参  不定长元组形参  缺省形参 不定长字典形参
    pass


# func1(1, 2, 3, 4)
# func2(1, 2, 3, 4)
func2(1, 2, 3, 4, b=10)


6、print函数中的sep

相当于是print函数默认的,自带空格属性,即缺省参数

# print(1)
# print(1, 2)
# print(1, 2, 3)
# print(1, 2, 3, 4)
# print(1, 2, 3, 4, 5)

print(1)
print(1, 2, sep='*')
print(1, 2, 3, sep='_*_')  # 1_*_2_*_3
print(1, 2, 3, 4, sep='hello')
print(1,2)  # 1 2
print(1, 2, 3, 4, 5, sep=' ')  # 默认  1 2 3 4 5

二、拆包

1、组包与拆包

# 组包,将多个数据值,组成元组,给到一个变量

# 拆包:将容器的数据分别给到多个变量,需要注意:数据的个数和变量的个数要保持一致

# 组包,将多个数据值,组成元组,给到一个变量
a = 1, 2, 3
print(a)  # (1, 2, 3)


def func():
    return 1, 2  # 组包


# 拆包:将容器的数据分别给到多个变量,需要注意:数据的个数和变量的个数要保持一致
b, c, d = a  # 拆包  把a的值分别给了b,c,d
print(b,c,d)

e,f = func()
print(e,f)  # 1 2

my_list = [10,20]
a,b = my_list
print(a, b)  # 10 20
my_dict = {'name': 'isaac', 'age': 18}
a, b = my_dict   # key值
print(a, b)  # name age

2、应用

可以在冒泡排序中使用!

直接交换两数的值,不需要第三个临时变量来辅助,本质上是拆包

a = 10
b = 20

# 方法一:
# c = a
# a = b
# b = c
# print(a, b)

# 方法二: +/-   */÷
# a = a + b  # a 30
# b = a - b  # 10
# a = a - b  # 20
'''后面的两次虽然书写上是一样的,但是意义不同'''
# print(a, b)

# 方法三, python中的使用 组包和拆包
a, b = b, a
print(a, b)

三、引用

1、变量的引用

本质上就是地址,

Python意思是数字都有地址,而变量是将自己的地址指向了数字(即将数字的地址保存在变量中)

# 可以使用 id() 查看变量的引用, 可以将id 值认为是内存地址的别名
# python中数据值的传递的是引用
# 赋值运算符可以改变变量的引用



# 将数据10 存储到变量a 中,  本质是将数据10 所在内存的引用地址保存到变量a 中
a = 10
# 将变量a中保存的引用地址给给到b
b = a
print(a, b)  # 使用print函数打印变量a 和 b 引用中存储的值
print(id(a), id(b))
a = 20
print(a, b)
print(id(a), id(b))

 2、列表的引用


my_list = [1, 2, 3]  # 将列表的引用地址保存到变量my_list 中
my_list1 = my_list  # 将my_list 变量中存储的引用地址给到 my_list1
print(my_list, id(my_list))
print(my_list1, id(my_list1))

my_list.append(4)  # 向列表中添加数据4, 将数据4 的引用保存到列表中
print(my_list, id(my_list))
print(my_list1, id(my_list1))

my_list[2] = 5
print(my_list, id(my_list))
print(my_list1, id(my_list1))
'''
列表的地址引用没有发生变化,属于可变类型(可以添加数据)
'''

 3、类型的可变与不可变

# 类型的可变与不可变: 在不改变变量引用的前提下,能否改变变量中引用中的数据,
# 如果能改变是可变类型, 如果不能改变,是不可变类型


# int float bool str list tuple dict
# 不可变类型:  int float bool str  tuple
# 可变类型: list dict

# num = 10
# num = 20
#
# my_list = [1, 2]
# my_list.append(3)

a = 1000
b = 1000
print(id(a), id(b))  # python中的内存优化,对于不可变类型进行的,
print(id(a) == id(b))

a = 'hello'
b = 'hello'
print(id(a), id(b))  # python中的内存优化,对于不可变类型进行的,

my_tuple = (1, 2)
my_tuple1 = (1, 2)
print(id(my_tuple), id(my_tuple1))
print(id(my_tuple) == id(my_tuple1))
print('-' * 20)
my_list = [1, 2, 3]
my_list1 = [1, 2, 3]
print(id(my_list), id(my_list1))

print('*' * 30)
my_tuple2 = (1, 2, [3, 4])
print(my_tuple2)
my_tuple2[2][1] = 10
print(my_tuple2)

4、引用作为函数参数传递

关系到到底要不要在函数中添加global 

# 函数传参传递的也是引用
my_list = [1, 2, 3]  # 全局变量


def func1(a):
    a.append(4)


def func2():
    # 为啥不加global, 因为没有修改 my_list 中存的引用值
    my_list.append(5)


def func3():
    global my_list
    my_list = [1, 2, 3]   # 修改全局变量的值


def func4(a):
    # += 对于列表来说,类似列表的extend方法,不会改变变量的引用地址
    a += a  # a = a + a, 修改了a变量a的引用
    # print(a)


func1(my_list)    # [1, 2, 3, 4]
func2()  # [1, 2, 3, 4, 5]
func3()  # [1, 2, 3]
print(my_list)

b = 10  # 不可变类型
func4(b)
print(b)  #

func4(my_list)
print(my_list)  # [1, 2, 3, 1, 2, 3]

四、学生管理系统(初步)(两种办法)

方法一

# 定义学生列表,保存所有的学生信息
stu_list = []


def show_menu():
    print('1. 添加学生')
    print('2. 删除学生')
    print('3. 修改学生信息')
    print('4. 查询单个学生信息')
    print('5. 查询所有的学生信息')
    print('6. 退出系统')


def insert_student():
    # 1. 通过 input 函数获取学生的信息, 姓名, 年龄, 性别
    name = input('请输入学生名字:')
    # [{}, {}, {}]  判断的是字典中的 value 是否存在
    for stu in stu_list:
        if stu['name'] == name:
            print('----------学生信息存在---------')
            return  # 结束函数的执行

    age = input('请输入学生年龄:')
    gender = input('请输入学生性别:')
    # 2. 将学生信息转换为字典进行保存
    stu_dict = {'name': name, 'age': int(age), 'gender': gender}
    # 3. 将这个学生字典添加的列表中
    stu_list.append(stu_dict)
    print('==============学生信息添加成功====================')


def remove_student():
    # 1. 使用 input 获取要删除 /修改/查询 的学生姓名
    name = input('请输入要操作的学生的名字:')
    # 2. 判断学生信息是否存在
    for stu in stu_list:
        if stu['name'] == name:
            # 3. 学生存在,对学生进行 删除 /修改/查询 操作
            stu_list.remove(stu)
            # return
            break
    # 4. 学生信息不存在,直接结束
    else:
        print('***********该学生信息不存在,无法删除**************')


def modify_student():
    # 1. 使用 input 获取要删除 /修改/查询 的学生姓名
    name = input('请输入要操作的学生的名字:')
    # 2. 判断学生信息是否存在
    for stu in stu_list:
        if stu['name'] == name:
            # 3. 学生存在,对学生进行 删除 /修改/查询 操作
            stu['age'] = int(input('请输入新的年龄:'))
            # return
            break
    # 4. 学生信息不存在,直接结束
    else:
        print('***********该学生信息不存在,无法修改**************')


def search_student():
    # 1. 使用 input 获取要删除 /修改/查询 的学生姓名
    name = input('请输入要操作的学生的名字:')
    # 2. 判断学生信息是否存在
    for stu in stu_list:
        if stu['name'] == name:
            # 3. 学生存在,对学生进行 删除 /修改/查询 操作
            print(f'姓名:{stu["name"]}, 年龄:{stu["age"]}, 性别:{stu["gender"]}')
            # return
            break
    # 4. 学生信息不存在,直接结束
    else:
        print('***********该学生信息不存在**************')


def show_all_info():
    if len(stu_list) > 0:
        for stu in stu_list:
            print(f'姓名:{stu["name"]}, 年龄:{stu["age"]}, 性别:{stu["gender"]}')
            # print(stu)
    else:
        print('目前没有学生信息')


def main():
    while True:
        show_menu()
        opt = input('请输入用来选择的操作编号:')
        if opt == '1':
            # print('1. 添加学生')
            insert_student()
        elif opt == '2':
            # print('2. 删除学生')
            remove_student()
        elif opt == '3':
            # print('3. 修改学生信息')
            modify_student()
        elif opt == '4':
            # print('4. 查询单个学生信息')
            search_student()
        elif opt == '5':
            # print('5. 查询所有的学生信息')
            show_all_info()
        elif opt == '6':
            print('欢迎下次使用本系统......')
            break
        else:
            print('输入有误,请再次输入')
            continue

        input('...... 回车键继续操作.......')


main()

方法二、

student = []


def main():
    while True:
        show()
        i = input("请输入操作编号:")
        if i == '1':
            insert()  # 添加
        elif i == '2':
            remove()  # 删除
        elif i == '3':
            modify()  # 修改
        elif i == '4':
            search()  # 查询
        elif i == '5':
            showAll()  # 查询所有信息
        elif i == '6':
            print("==========欢迎下次使用本系统==========")
        else:
            print("==========输入有误,请再次输入!==========")
        continue

        input("==========按回车键继续==========")


def show():
    print('1. 添加学生')
    print('2. 删除学生')
    print('3. 修改学生信息')
    print('4. 查询单个学生信息')
    print('5. 查询所有的学生信息')
    print('6. 退出系统')


def insert():
    """
    添加学生信息
    """
    name = input("请输入学生的姓名:")
    for s in student:
        if s['name'] == name:
            print("该学生信息已存在,请再次输入指令!")
            return
    age = input("请输入学生的年龄:")
    sex = input("请输入学生的性别:")
    stu_dict = {'name': name, 'age': age, 'sex': sex}
    student.append(stu_dict)
    print('==========学生信息添加完成==========')


def remove():
    name = input('请输入要删除的学生的姓名:')
    for stu in student:
        if stu['name'] == name:
            # 3. 学生存在,对学生进行 删除 /修改/查询 操作
            student.remove(stu)
            # return
            break
    else:
        print('==========该学生信息不存在,无法删除==========')


def modify():
    # 1. 使用 input 获取要删除 /修改/查询 的学生姓名
    name = input('请输入要操作的学生的名字:')
    # 2. 判断学生信息是否存在
    for stu in student:
        if stu['name'] == name:
            # 3. 学生存在,对学生进行 删除 /修改/查询 操作
            stu['age'] = int(input('请输入新的年龄:'))
            # return
            break
    # 4. 学生信息不存在,直接结束
    else:
        print('==========该学生信息不存在,无法修改==========')


def search():
    # 1. 使用 input 获取要删除 /修改/查询 的学生姓名
    name = input('请输入要操作的学生的名字:')
    # 2. 判断学生信息是否存在
    for stu in student:
        if stu['name'] == name:
            # 3. 学生存在,对学生进行 删除 /修改/查询 操作
            print(f'姓名:{stu["name"]}, 年龄:{stu["age"]}, 性别:{stu["gender"]}')
            # return
            break
    # 4. 学生信息不存在,直接结束
    else:
        print('==========该学生信息不存在==========')


def showAll():
    if len(student) > 0:
        for stu in student:
            print(f'姓名:{stu["name"]}, 年龄:{stu["age"]}, 性别:{stu["gender"]}')
            # print(student)
    else:
        print('目前没有学生信息')


main()

五、练习

1、

"""
如下所示这是一个字典,{"name":"电脑","price":7000}

请定义这样一个函数num,讲上述字典中的键值对传入到函数num中,要求用不定长参数来接收,并在函数中打印键值对输出

输出格式为:

key: name value: 电脑
key: price value: 700
"""


def num(**kwargs):
    for key, value in kwargs.items():
        print("key:", key, "value:", value)


num(name="电脑", price=700)

2、

"""
对于一个函数num,当调用nun(1,2,a=3,b=4)和调用num(3,4,5,6,a=1)以及num(a=1,b=2)的时候都可以正常运行,并且可以对元组以及字典类型进行遍历输出,对字典类型进行输出字典的键值对(形式为:key:a,value:1),

请写出这个函数并完成调用。
"""


def num(*args, **kwargs):
    for i in args:
        print(i)
    for key, value in kwargs.items():
        print("key:", key, "value:", value)


num(1, 2, 3, a=1, b=2)
# num(a=1, b=2)  此种情况也可

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

名之以父

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值