python基础(9)——函数的参数传递

一、python 函数的参数传递

传递方式:
    位置传参
    序列传参
    关键字传参
    字典关键字传参

1、位置传参:

    实际参数(实参)的对应关系与形式参数(形参)的对应关系是接位置来依次对应的.

1、示意:
     def mymin(a, b, c):
        pass

     mymin(1, 2, 3)  # 1,2,3位置位置对应关系传给a,b,c
2、说明:
     实际参数和形式参数通过位置进行传递和匹配
     实际参数的个数必须与形式参数的个数相同

# 位置传参
def myfun(a, b, c):
    '这是一个函数传参的示例'
    print('a的值是:', a)
    print('b的值是:', b)
    print('c的值是:', c)


myfun(1, 2, 3)
myfun(4, 5, 6)
myfun(5, 6, 4)
positional_give_args.py

2、序列传参:

    序列传参是指在函数调用过程中,用*将序列拆解后按位置进行传递的传参方式

说明:
     序列传参时,序列拆解的位置将与形参一一对应
     序列的位置信息对应相应的参数位置

 1 # 序列传参
 2 def myfun(a, b, c):
 3     '这是一个函数传参的示例'
 4     print('a的值是:', a)
 5     print('b的值是:', b)
 6     print('c的值是:', c)
 7 
 8 
 9 s1 = [11, 22, 33]
10 s2 = (44, 55, 66)
11 s3 = "ABC"
12 myfun(*s1)  # 等同于 myfun(s1[0], s1[1], s1[2])  # 11 -->a, 22 --> b, 33 --> c
13 myfun(*s2)  # 等同于 myfun(s2[0], s2[1], s2[2])
14 myfun(*s3)  # 等同于 myfun(s3[0], s3[1], s3[2])
sequence_give_args.py

3、关键字传参

   关键字传参是指传参时,按着形参的名称给形参赋值
   实参和形参按名称进行匹配
1、示意:
     def myfun(a, b, c):
         pass
     myfun(b=22, c=33, a=11)  # 11->a,22->b,33->c
     myfun(c=66, b=55, a=44)  # 44->a,55->b,66->c
2、说明:
     实参和形参按着形参名进行匹配,可以不按位置进行匹配

# 关键字传参
def myfun(a, b, c):
    '这是一个函数传参的示例'
    print('a的值是:', a)
    print('b的值是:', b)
    print('c的值是:', c)


myfun(c=33, b=22, a=11)
myfun(b=200, c=300, a=100)
myfun(a=100, b=200, c=300)
keywords_give_args.py

4、字典关键字传参:

   是指实参为字典,将字典用 ** 拆解后进行关键字传参的方式

说明:
     字典的键名和形参名一致
     字典的键名必须为字符串(且为标识符的命名方式)
     字典的键名要在形参中存在

# 字典关键字传参
def myfun(a, b, c):
    '这是一个函数传参的示例'
    print('a的值是:', a)
    print('b的值是:', b)
    print('c的值是:', c)

d1 = {'c': 300, 'b': 200, 'a': 100}

myfun(**d1)    # 等同于 myfun(a=100, b=200, c=300)
# myfun(a=d1['a'], b=d1['b'], c=d1['c'])  # 100-->a  200-->b  300-->c
d2 = {'c': 300, 'b': 200, 'd': 400}
myfun(**d2)
dict_keywords_give_args.py

五、函数的综合传参

   函数的传参方式,在能确定形参能唯一匹配到相应实参的情况下可以任意组合
   函数的位置传参要先于关键字传参

说明:
    1. 位置传参和序列传参可以混合使用且可以顺序颠倒
       如:
         myfun(100, *[200, 300])
         myfun(*[100, 200], 300)
         myfun(*[100], 200, *[300])
    2. 函数的关键字传参和字典关键字传参可以混合使用,且可以顺序颠倒
       如:
         myfun(c=300, **{'b':200, 'a': 100})
         myfun(**{'b':200, 'c': 300}, a=100)
    3. 位置传参和关键字传参可以混合使用,但位置传参要先于关键字传参:
       如:
         myfun(100, c=300, b=200)
         myfun(10, c=30, **{'b': 20})

练习:
   写一个函数 getminmax(a, b, c) 有三个参数
   此函数用于返回三个数的最大值,最小值形成元组后返回
        元组格式:
              (最小值, 最大值)

   可以偿试上述传参方式

 1 def getminmax(a, b, c):
 2     xiao = min(a, b, c)
 3     da = max(a, b, c)
 4     return xiao, da
 5 
 6 # a = int(input("请输入第1个数: "))
 7 # b = int(input("请输入第2个数: "))
 8 # c = int(input("请输入第3个数: "))
 9 
10 # t = getminmax(a, b, c)
11 # t = getminmax(a=a, b=b, c=c)
12 L = []
13 for i in range(1, 4):
14     L.append(int(input("请输入第%d个数: " % i)))
15 
16 t = getminmax(*L)
17 print(t)
18 print("最小数是:%d, 最大数是:%d" % (t[0], t[1]))
19 print("最小数是:%d, 最大数是:%d" % t)
练习.py

---------------以下讲函数的定义时如何定义形参----------------

二、Python函数中定义形参

(一)函数的缺省参数

1、语法:
     def 函数名(形参名1=默认实参1, 形参名2=默认实参2, ... ):
       语句块

 1 # 函数的缺省参数
 2 def info(name, age=1, address='不详'):
 3     print('我叫', name, '我今年',
 4           age, '岁,我的住址:', address)
 5 
 6 
 7 info('小明', 35, '朝阳区')
 8 info('Tarena', 15)  # <--两个参数调用
 9 info('张飞')
10 # info()  # 出错
default_args.py

2、说明:
     缺省参数必须自右至左依次存在.如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数
     缺省参数可以有0个或多个,甚至全部都有缺省参数
3、示例:
     def fn(a, b=10, c):  # 错的
         pass
     def fn(a=100, b=200, c=300):  # 对的
         pass

练习1:
   写一个函数 myadd,  此函数可以计算两个,三个,四个实参的和
   def myadd(...):
      ....

   print(myadd(100, 200))  # 300
   print(myadd(100, 200, 300))  # 600
   print(myadd(100, 200, 300, 400))  # 1000
   print(myadd(100, 200, 300, 400, 500))  # 报错

def myadd(a, b, c=0, d=0):
    return a + b + c + d


print(myadd(100, 200))  # 300
print(myadd(100, 200, 300))  # 600
print(myadd(100, 200, 300, 400))  # 1000
# print(myadd(100, 200, 300, 400, 500))  # 报错
练习1.py

练习2:
   写一个myrange函数: 此函数用给定的参数,返回一个存有对应整数的列表
   如:
     def myrange(start, stop=None, step=1):
         ...

    L = myrange(5)  # L = [0, 1, 2, 3, 4]
     L = myrange(5, 10)  # L = [5, 6, 7, 8, 9]
     L = myrange(5, 10, 2)  # L = [5, 7, 9]
     for x in myrange(5, 10, 2):
         print(x)   # 5 7 9

def myrange(start, stop=None, step=1):
    if stop is None:
        stop = start  # 让 start作用终止步
        start = 0  # 起始值设置为0
    # print("起始值:", start, '终止值:', stop, '步长:', step)
    L = []
    i = start
    if step > 0:
        while i < stop:
            L.append(i)
            i += step
    elif step < 0:  # 步长小于零
        while i > stop:  # 当i比stop大时,i是生成的数
            L.append(i)
            i += step  # i的值变小
    return L


L = myrange(5)  # L = [0, 1, 2, 3, 4]
print(L)
L = myrange(5, 10)  # L = [5, 6, 7, 8, 9]
print(L)
L = myrange(5, 10, 2)  # L = [5, 7, 9]
print(L)
for x in myrange(3, 10, 2):
    print(x)   # 3 5 7 9
print("---------------------------------")
for x in myrange(10, 0, -2):
    print(x)  # 10 8 6 4 2
练习2.py

(二)函数形参的定义方式:

      位置形参
      星号元组形参
      命名关键字形参
      双星字典形参

1、位置形参

   def 函数名(形参名1, 形参名2, ...):
       语句块

2、星号元组形参

 1、语法:
     def 函数名(*元组形参名):
       语句块
 2、作用:
     收集多余的位置传参
 3、说明:
     元组形参名一般命名为'args'

star_tuple_args1.py
# 此示例示意星号元组形参的用法2
def func(a, b, *args):
    print('a=', a)
    print('b=', b)
    print("args =", args)


func(1, 2, 3, 4, 5)
star_tuple_args2.py

练习:
   写一个函数 mysum 可以传入任意个实参的数字,返回所有实参的和
   def mysum(*args):
     ....

   print(mysum(1, 2, 3, 4))  # 10
   print(mysum(1, 2, 3, 4, 5, 6))  # 21

# 方法1
def mysum(*args):
    s = 0
    for x in args:
        s += x
    return s


# 方法2
def mysum(*args):
    return sum(args)


print(mysum(1, 2, 3, 4))  # 10
print(mysum(1, 2, 3, 4, 5, 6))  # 21
练习1.py

练习:
   已知内建函数max帮助文档为:
     >>> help(max)
       max(iterable) -> value
       max(arg1, arg2, *args) -> value
     仿造max,写一个mymax函数,功能要求与max完全相同
     (要求,不允许调用max函数)

     print(mymax([6, 8, 3, 5]))  # 8
     print(mymax(100, 200))  # 200
     print(mymax(1, 3, 5, 9, 7))  # 9

# 方法1
def mymax(a, *args):
    if not args:  # 元组为空,只是a绑定一个可迭代对象
        zuida = a[0]  # 先假设第一个数最大
        for x in a:
            if x > zuida:
                zuida = x
        return zuida
    else:  # 调用者传入的有两个或两个以上的实参
        zuida = a  # 先假设第一个参数最大
        for x in args:
            if x > zuida:
                zuida = x
        return zuida


# 方法2
def mymax(a, *args):
    if not args:  # 元组为空,只是a绑定一个可迭代对象
        zuida = a[0]  # 先假设第一个数最大
        for x in a:
            if x > zuida:
                zuida = x
    else:  # 调用者传入的有两个或两个以上的实参
        zuida = a  # 先假设第一个参数最大
        for x in args:
            if x > zuida:
                zuida = x
    return zuida


# 方法3
def mymax(a, *args):
    if not args:  # 元组为空,只是a绑定一个可迭代对象
        return max(a)
    else:  # 调用者传入的有两个或两个以上的实参
        return max(a, max(args))


# 方法4
def mymax(a, *args):
    if not args:  # 元组为空,只是a绑定一个可迭代对象
        return max(a)
    else:  # 调用者传入的有两个或两个以上的实参
        return max(a, *args)


print(mymax([6, 8, 3, 5]))  # 8
print(mymax(100, 200))  # 200
print(mymax(1, 3, 5, 9, 7))  # 9
练习2.py

3、命名关键字形参:

 1、语法:
     def 函数名(*, 命名关键字形参):
         语句块
     或
     def 函数名(*args, 命名关键字形参):
         语句块
 2、作用:
     强制所有的参数都必须用关键字传参或字典关键字传参

# 此示例示意命名关键字传参
def fun(*, c, d):
    print('c=', c)
    print('d=', d)


# fun(3, 4)  # 出错
fun(d=4, c=3)  # 正确

def fun2(a, b, *, c, d):  # *是位置形参和关键形参的分隔符
    print(a, b, c, d)


fun2(1, 2, c=3, d=4)

def fun3(a, b, *args, c, d):
    print(a, b, args, c, d)


fun3(11, 22, 33, 44, 55, d=400, c=300)
fun3(1, 2, **{'d': 4, 'c': 3})
named_keyword_args.py

4、双星号字典形参

 1、语法:
     def 函数名(**字典形参名):
         语句块
 2、作用:
     收集多余的关键字传参
 3、说明:
      字典形参名一般命名为 kwargs

# 此示例示意双星号字典形参
def fun(**kwargs):
    print("关键字传参的个数是:", len(kwargs))
    print('kwargs=', kwargs)


fun(name='weimingze', age=35, address='北京市朝阳区')
fun(a=1, b="BBBB", c=[2, 3, 4], d=True)
fun(a=100, **{'c': 300, 'b': 200}, d=400)
double_star_dict_args.py

(三)函数的参数说明:

     位置形参,缺省参数,星号元组形参,双星号字典形参等可以混合使用

 1、函数参数自左至右的顺序为:
     1. 位置形参
     2. 星号元组形参
     3. 命名关键字形参
     4. 双星号字典形参
 示例:
     def fn(a, b, *args, c, **kwargs):
         pass
     fn(100, 200, 300, 400, d='D', e='E', c='C')

2、思考题:
  查看:
     >>> help(print)
   猜想print函数的参数列表是如何定义的
  答:
     def myprint(*args, sep=' ', end='\n'):
         pass

练习:

   1. 写一个函数mysum(n) ,此函数用来计算
      1+2+3+4+....+n的和
     如:
       print(mysum(100))  # 5050

 1 def mysum(n):
 2     s = 0
 3     for x in range(1, n + 1):
 4         s += x
 5     return s
 6 
 7 
 8 print(mysum(100))  # 5050
 9 print(mysum(1000))
10 print(mysum(10000))
练习1.py

  2. 实现带有界面的学生信息管理系统
     操作界面:
       +-------------------------+
       | 1)  添加学生信息              |
       | 2)  显示学生信息              |
       | 3)  删除学生信息              |
       | 4)  修改学生信息              |
       | q)  退出                        |
       +-------------------------+
       请选择: 1

    修改之前学生信息管理程序,学生信息依旧为:
          姓名,年龄,成绩
     要求: 每个功能写一个函数与之相对应

  示意:
     def main():
         L = []
         while True:
             # 此处先显示菜单
             s = input("请选择: ")
             if s == 'q':
                 break
             elif s == '1':
                 L += input_student()
             elif s == '2':
                 output_student(L)
             ...
     main()

 1 def input_student():
 2     L = []  # 创建一个新的列表,用此列表准备保存学生信息
 3     # 录入学生信息
 4     while True:
 5         n = input("请输入姓名: ")
 6         if not n:
 7             break
 8         a = int(input("请输入年龄: "))
 9         s = int(input('请输入成绩: '))
10         # 创建一个新的字典,把学生的信息存入字典中
11         d = {}  # 每一次都重新创建一个新的字典
12         d['name'] = n
13         d['age'] = a
14         d['score'] = s
15         L.append(d)
16     return L
17 
18 
19 def get_chinese_char_count(x):
20     count = 0  # 先假设个数为0
21     for ch in x:
22         # 如果ch为中文字典,则count 做加一操作
23         if ord(ch) > 127:
24             count += 1
25     return count
26 
27     
28 def output_student(L):
29     print("+---------------+----------+----------+")
30     print("|     name      |   age    |   score  |")
31     print("+---------------+----------+----------+")
32     for d in L:
33         n = d['name']
34         a = d['age']
35         s = d['score']
36         chinese_cnt = get_chinese_char_count(n)
37         print('|%s|%s|%s|' % (n.center(15-chinese_cnt),
38                               str(a).center(10),
39                               str(s).center(10)
40                               )
41               )
42 
43     # print("|    tarena     |    20    |     99   |")
44     # print("|     name2     |    30    |     88   |")
45     print("+---------------+----------+----------+")
46 
47 
48 def del_student(L):
49     n = input('请输入要删除的学生的姓名: ')
50     print("正在删除....", n)
51 
52 
53 def modify_student_score(L):
54     print("正在修改学生成绩....")
55 
56 
57 def show_menu():
58     print("+---------------------------+")
59     print("| 1)  添加学生信息          |")
60     print("| 2)  显示学生信息          |")
61     print("| 3)  删除学生信息          |")
62     print("| 4)  修改学生成绩          |")
63     print("| q)  退出                 |")
64     print("+---------------------------+")
65 
66 
67 def main():
68     L = []
69     while True:
70         show_menu()
71         s = input("请选择: ")
72         if s == 'q':
73             break
74         elif s == '1':
75             L += input_student()
76         elif s == '2':
77             output_student(L)
78         elif s == '3':
79             del_student(L)
80         elif s == '4':
81             modify_student_score(L)
82 
83 
84 main()
练习2.py

posted on 2018-10-12 17:24  破天荒的谎言、谈敷衍  阅读(484)  评论(0)    收藏  举报

导航