(九)python 传参,函数定义

目录

函数的定义:

return 语句

函数的参数传递

    位置传参:

       序列传参:

    关键字传参:

    字典关键字传参:

    函数的综合传参:

函数的定义和创建时形参的定义

    函数形参的定义方式:

    函数的参数说明:


函数的定义:

    def 函数名(形参列表)
        语句块
    作用:
        创建一个函数,把函数内的语句块打包为一个函数,用函数名绑定

函数调用:
    函数名(实参列表)

问题:
    def mysum(a,b):
        print(a + b)

    r = mysum(100,200)
    print(r)  #请问r绑定的是什么? #300

函数说明:
    函数外部无法访问函数内部的局部变量
    函数内部可以访问函数外部的变量,但不能修改函数外部变量的绑定关系
    例如:

        x = 0
        def myadd(a,b):
            x = a + b
            print(x)
        myadd(100,200)
        print(x)  #0

return 语句

    语法:
        return [表达式]
        注: [] 代表内容可省略
    作用:
        用于函数中,结束当前的函数的执行,返回到调用该函数的地方,同时返回表达式的引用关系
    说明:
        return 语句后跟的表达式可以省略,省略后相当于return None
    如果函数内没有return语句,则函数执行玩最后一条语句后返回None(相当于在最后加了一条 return None语句)

def say_hello():
    print("1")
    print("2")
    return "你好"
    print("3")

r = say_hello()
print(r)  # None
# say_hello()


练习:
    1.写一个函数mymax,实现返回两个数的最大值:
    如:
        def mymax(a,b):
            ...
            print(mymax(100,200))  #200
            print(mymax("ACB","ABC"))  #ACB

#方法1 经典算法
def mymax(a, b):
    zuida = a  # 求最大值用变量zuida绑定
    if b > zuida:
        zuida = b   
    return zuida  # 把zuida绑定的数据送回给调用

#方法2
def mymax(a, b):
    if a > b:
        return a
    else:
        return b

#方法3
def mymax(a, b):
    if a > b:
        return a
    return b

#方法4
def mymax(a, b):
    return a if a > b else b

#方法5
def mymax(a, b):
    return max(a, b)

print(mymax(100, 200))  # 200
print(mymax("ACB", "ABC"))  # ACB


    2.写一个函数input_number
        def input_number():
            此处自己实现
    此函数用来获取用户循环输入的整数,当输入负数时结束输入,将用户输入的数字以"列表"的形式返回,
    再用内建函数max,min,sum求出用户输入的最大值,最小值和平均值
        L = input_number()
        print(L)  #打印用户输入的列表
        print("用户输入的最大值是:",max(L))
        print("用户输入的最小值是:",min(L))
        print("用户输入的平均值是:",max(L)/len(L))

def input_number():
    L = []  # 创建一个列表,准备存储数字
    # 此处自己实现
    while True:
        n = int(input("请输入一个正整数"))
        if n < 0:
            break
        L.append(n)
    return L

L = input_number()
print(L)  # 打印用户输入的列表
print("用户输入的最大值是:", max(L))
print("用户输入的最小值是:", min(L))
print("用户输入的平均是:", sum(L)/len(L))


函数的参数传递

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

    位置传参:

         实际传递参数(以下简称"实参")与形式参数(形参)的对应关系按位置来依次对应

#示例:
def myfun(a, b, c):
"""注意此函数不会变化"""
print('a =', a)
print('b =', b)
print('c =', c)
myfun(1, 2, 3)

       序列传参:

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


    关键字传参:

        关键字传参是指传参时,按着形参的名称给形参赋值
        实参和形参按名称进行匹配

# 此示例示意序列传参

def myfun(a, b, c):
    """注意此函数不会变化"""
    print('a =', a)
    print('b =', b)
    print('c =', c)

s = "ABC"
L = [4,5,6]
t = (1.1, 2.2, 3.3)

# myfun(s[0], s[1], s[2])  # 按位置传
myfun(*s)
myfun(*L)
myfun(*t)
# 此示例示意关键字传参
def myfun(a, b, c):
    """注意此函数不会变化"""
    print('a =', a)
    print('b =', b)
    print('c =', c)

myfun(b=2, c=3, a=1)
myfun(c=333, b=222, a=111)

# 以下是错误的
# myfun(a=2, c=3, a=1)
# myfun(d=2, c=3, a=1)


    字典关键字传参:

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

# 此示例示意字典关键字传参
def myfun(a, b, c):
    """注意此函数不会变化"""
    print('a =', a)
    print('b =', b)
    print('c =', c)

d = {'a':111, 'c':333, 'b': 222}
myfun(**d)  # 等同于 myfun(a=111,c=333,b=222)

# 以下是错误传法
# d2 = {1: '一', 'c':333, 'b': 222}
# myfun(**d2)


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

    函数的综合传参:

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

# 此示例示意函数的组合传参

def myfun(a, b, c):
    """注意此函数不会变化"""
    print('a =', a)
    print('b =', b)
    print('c =', c)

# myfun(1, c=3, b=2)  # 正确
# myfun(b=2, a=1, 3)  # 错的
myfun(100, *[200, 300])  # 正确 
myfun(*"AB", 300)  # 正确
myfun(*[100], c=300, b=200)  # 正确
myfun(*"AB", **{"c":300})  # 正确


练习:
    1.利用上题input_number获取用户输入的数字列表
    2.写一个函数split_number(L)传入得到的列表
      将所有的数字分为奇数和偶数,分别放在两个列表odds和 evens中
      同时返回这两个列表打印其中的数据
      def split_number(L):
          此处自己实现
      L = input_number()  #1,2,3,4,5,6
      t = split_number(L)  #返回一个元组,元组里放两个列表
      odds, evens = t
      print("所有的奇数是:",odds)   #[1,3,5]
      print("所有的偶数是:",evens)  #[2,4,6]

def input_number():
    L = []  # 创建一个列表,准备存储数字
    # 此处自己实现
    while True:
        n = int(input("请输入一个正整数"))
        if n < 0:
            break
        L.append(n)
    return L


def split_number(L):
    L1 = []  # 用来存放奇数
    L2 = []  # 创建一个列表,用来存放偶数
    for x in L:
        if x % 2 == 1:
            L1.append(x)
        else:
            L2.append(x)
    return (L1, L2)  # 打包成为元组后返回


lst = input_number()  # 1, 2, 3, 4, 5, 6
t = split_number(lst)  # 返回一个元组,元组里放两个列表

odds, evens = t
print("所有的奇数是:", odds)  # [1, 3, 5]
print("所有的偶数是:", evens)  # [2, 4, 6]

函数的定义和创建时形参的定义

    函数的缺省参数
        语法
            def 函数名(形参名1=默认实参1,形参名2=默认实参2,...)

# 此程序示意函数的缺省参数
def info(name, age=1, address="未填写"):
    print(name, "今年", age, "岁, 住在:", address)

# info()  # 出错,至少得给一个实参给name绑定
info('小李')
info('tarena', 15)
info('小魏', 3, '北京市朝阳区')

    说明:
        1.缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数
            def  fa(a = 1 , b , c = 3)   # 是错的
            def  fb(a, b=10 , c)   # 是错的
        2.缺省参数可以右0个或多个,甚至全部都是缺省参数

练习:
    写一个函数 myadd, 此函数可以计算两个数的和,也可以计算三个数的和
        def myadd(......):
                  .....此处自己实现
        print(myadd(10,20))  # 30
        print(myadd(100,200,300))  # 600

def myadd(a,b,c=0):
    return  a + b + c   
print(myadd(10,20))  #30
print(myadd(100,200,300))  # 600

    函数形参的定义方式:

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

    位置形参:
        语法:
            def 函数名(形参名1,形参名2,...):
                语句块
    星号元组形参:
        语法:
            def 函数名(*元组形参名):
                语句块
        作用:
            收集多余的位置传参

练习:
    写一个函数mysum(可以传入任意个实参,反回所有实参的和)
    def mysum(*args):
        ...
    print(mysum(1,2,3,4))    #  10
    print(mysum(5,6,7,8,9,10))    #  45

def mysum(*args):
    return sum(args)
print(mysum(1,2,3,4))    #  10
print(mysum(5,6,7,8,9,10))    #  45 


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

# 此示例示意函数的命名关键字形参
def fa(a, b, *, c, d):
    '''强制c,d必须用关键字传参 '''
    print(a, b, c, d)

fa(1, 2, d=400, c=300)  # 对的

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

fb(1, 2, 3, 4, d=400, c=200)
fb(1,2,3,4,5, **{'d':400, 'c':300})

# 问题:
# fb(1,2,3,4, c=400, d=300, e=500)  # 出错,e是多余的

# fa(1, 2, 3, 4)  # 错的


    双星号字典形参
        语法:
            def 函数名(**字典形参名):
                语句
        作用:
            收集多余的关键字传参

# 此示例示意双星号字典形参的用法
def fa(**kwargs):
    '''kwargs绑定字典'''
    print("多余的关键字传参的个数是:", len(kwargs))
    print("kwargs =", kwargs)

fa(a=10, b=20, c=30)

def fb(*args, a, **kwargs):
    print(args, a, kwargs)

fb(1,2,3, b=20, c=30, a=10)


    函数的参数说明:

        位置形参,星号元组形参,命名关键字形参,双星号字典形参,缺省参数可以混合使用
        函数参数自左至右的顺序依次为:
            位置形参
            星号元组形参
            命名关键字形参
            双星号字典形参

#示例:
def fn(a,b,*args,c,d,**kwargs):
      pass
  fn(1,2,3,4, c=100,d=200,e=300,f=400)

练习:
1.思考题:
    查看:
    >>> help(print) 猜想print函数的参数列表是如何定义的???
2. 写一个myrange函数,参数可以传1~3 个,实际意义同range函数规则相同,此函数返回符合range(...) 函数规则的列表
    如:
        L = myrange(4)
        print(L)  #[0,1,2,3]
        L = myrange(4,6)
        print(L)  #[4,5]
        L = myrange(1,10,3)
        print(L)  #[1,4,7]

#方法1
def myrange(start, stop=None, step=1):
    r_lst = []   #即将返回的列表
    #调整三个形参的值
    if stop is None:
        stop = start
        start = 0

    if step > 0:
        while start < stop:
            r_lst.append(start)   #把当前数加入到列表中
            start += step   #让start 向后移动,准备下次操作
    else:   #当步长小于0的情况
        for x in range(start, stop, step):
            r_lst.append(x)
     # 此处把符合条件的数据加到列表r_lst中
    return r_lst

# 方法2
def myrange(start, stop=None, step=1):
    # 调整三个形参的值
    if stop is None:
        stop = start
        start = 0

    return list(range(start, stop, step))

L = myrange(4)
print(L)  # [0, 1, 2, 3]
L = myrange(4, 6)
print(L)  # [4, 5]
L = myrange(1, 10, 3)
print(L)  # [1, 4, 7]
L = myrange(10, 1, -3)
print(L)

练习:
    1.算出100~999之间的水仙花数(Narcissistic number)
      水仙花数是指百位的3次方加上十位的3次方 加上个位的3次方等于原数的整数
      例如:
        153 等于1 ** 3 + 5 ** 3 + 3 ** 3
        建议,先写一个数is_narcissistic(n)
        来判断n是否为水仙花数,如果是返回True,否则返回False
        再调用此函数进行判断

    2.求100以内的全部素数(质数)       
        2 3 5 7 11...
        建议用函数来做
        两个函数:
            def is_prime(x):
                '''判断x是否为素数,如果是素数返回True,否则返回False'''
                ....
            def print_primes(n):
            '''此函数打印小于n的全部素数

    3.将上次的student_info.py改写为两个函数:   
        1)  def input_student():
            '''此函数返回用户输入的学生信息的列表
            返回的列表格式与之前完全相同
            .........
        2) def output_student(L):
               '''此函数把传入的列表L打印成为表格'''
               ......
        主程序调用:
        docs = input_student()
        output_student(does)
        print("请再添加几个学生信息...")
        docs += input_student()
        print("添加之后的学生信息是...")
        output_student(does)

#第一题
#方法1
for x in range(100, 1000):
    bai = x // 100  # 百位
    shi = x % 100 // 10  # 十位
    ge  = x % 10  # 个位
    if x == bai ** 3 + shi ** 3 + ge ** 3:
        print(x)

#方法2
for x in range(100, 1000):
    s = str(x)  # 转成字符串
    bai = int(s[0])  # 百位
    shi = int(s[1])  # 十位
    ge  = int(s[2])  # 个位
    if x == bai ** 3 + shi ** 3 + ge ** 3:
        print(x)

# 方法3 
# 先定义一个函数 is_narcissistic
def is_narcissistic(x):
    '''判断如果x是水仙花数就返回True'''
    bai = x // 100  # 百位
    shi = x % 100 // 10  # 十位
    ge  = x % 10  # 个位
    if x == bai ** 3 + shi ** 3 + ge ** 3:
        return True
    return False

for x in range(100, 1000):
    if is_narcissistic(x):
        print(x)  # 打印水仙花数
#第二题
def is_prime(x):
    '''判断x是否为素数,如果是素数返回True,
    否则返回False'''
    if x < 2:
        return False
    # 走到此处时,x 一定大于等于2
    for i in range(2, x):
        if x % i == 0:  # 能整除就一定不是素数
            return False
    return True
  
def print_primes(n):
    '''此函数打印小于 n的全部素数'''
    for x in range(n):
        if is_prime(x):
            print(x, end=' ')
    print()  # 换行

print_primes(100)  # 开始打印....
def input_student():
    '''此函数返回用户输入的学生信息的列表
    返回的列表格式写之前完全相同
    '''
    L = []  # 创建一个列表,用来保存所有学生的字典
    # 读取学生数据放入列表中
    while True:
        n = input("请输入学生姓名: ")
        if not n:  # 如果学生姓名为空则结束输入
            break
        a = int(input("请输入学生年龄: "))
        s = int(input("请输入学生成绩: "))
        # 把上述n, a, s 所表示的信息形成字典,并加入到列表
        d = {}  # 创建一个新字典,准备存入学生信息数据
        d['name'] = n
        d['age'] = a
        d['score'] = s
        L.append(d)  # 把字典存入列表中
    return L

def output_student(L):
    '''此函数把传入的列表L 打印成为表格'''
    # 第二步,显示所有学生的信息
    print("+---------------+----------+----------+")
    print("|      name     |    age   |  score   |")
    print("+---------------+----------+----------+")
    # 此处打印所有学生的信息
    for d in L:  # 把每个学生的数据取出来,用d绑定对应的字典
        center_name = d['name'].center(15)
        str_age = str(d['age'])  # 先将年龄转为字符串
        center_age = str_age.center(10) # 生成居中的字符串
        center_score = str(d['score']).center(10)
        line = "|%s|%s|%s|" % (center_name,
                              center_age,
                              center_score)
        print(line)
    print("+---------------+----------+----------+")


def main():
    docs = input_student()
    output_student(docs)
    print("请再添加几个学生信息...")
    docs += input_student()
    print("添加之后的学生信息是")
    output_student(docs)

main()

猜你喜欢

转载自blog.csdn.net/zh__quan/article/details/81837851