zoukankan      html  css  js  c++  java
  • python函数基础-参数-返回值-注释-01

    什么是函数

    函数就是有特定功能的工具 # python中有内置函数(python解释器预先封装好的)与自定义函数(用户自定义封装的)之分 

    为什么要用函数

    # 可以减少代码冗余,增加代码复用性
    # 使代码逻辑更加清晰
    # 一次编写,任意次数调用

    函数定义

    '''
    精简版定义:
    def 函数名():
        代码体
    
    调用:
    函数名()
    '''

    函数名命名规范 # 函数名的命名规则与变量名的一模一样 ,千万注意两点 # 不能以关键字作为函数名,避免与内置函数重名(比如内置函数 len)(******) , # 函数也应该做到见名知意 

    函数的定义及执行顺序

    注意点

    '''
    函数在定义阶段只检测语法,不执行代码
        比如里面写多了一个 if  后面就没了,运行就会报错
        执行的时候,代码有问题才会报错了
    
    变量可以通过变量名找到对应的值
    函数可以通过 函数名 加 括号 找到函数体所对应的的代码并执行
    
    函数必须先定义后调用(函数名+括号)
    定义了之后的函数可以在任意位置调用
    '''

    函数的一种特殊应用

    空函数: 在项目的初期应用频率非常高,可以快速构建项目框架,使项目架构与进度清晰明了(还有几个功能(pass)没写) 

    # 可以直接罗列出功能名,也可以给出一些参数
    def register():
        pass
    
    
    def login():
        pass
    
    
    def print_shop_list():
        pass
    
    
    def choice_shop():
        pass
    
    
    def pay():
        pass

    return关键字

     # 函数要想返回给调用者一个值,就必须使用return 关键字 

    函数返回值 # 测试函数有无返回值可用变量接收,None 其实也是一种特殊的返回值 

    # 函数返回值的五种情况(出于演示,就不注重函数前后空行的代码标准(PEP8规范)了)
    # 1.不写return
    def func_no_return():
        print(1, 2, 3)
    print(func_no_return())  # 接收到的是None
    # 1 2 3
    # None
    
    # 2.return后面什么也不跟
    def func_just_return():
        print(1, 2, 3)
        return
        print("hello world.")  # 这一句print 并未被执行
    print(func_just_return())  # 接收到的是None
    # 1 2 3
    # None
    
    # 3.写return None
    def func_return_none():
        print(1, 2, 3)
        return None
    print(func_return_none())  # 接收到的是None
    # 1 2 3
    # None
    
    # 4.写return 返回一个值
    def func_return_one():
        print(1, 2, 3)
        return 1
    print(func_return_one())  # 接收到的是返回值 1, 这个值可以是python的任意数据类型
    # 1 2 3
    # 1
    
    # 5.写return多个值
    def func_return_many():
        print(1, 2, 3)
        return 1, 2, 3
    print(func_return_many())  # 接收到的是一个元组,包裹上这三个元素,想要多个返回值不被包装成元组返回,可以选择将其整体包装成一个大类型(例如列表,最外层在套一个列表 [[1,2,3]. [1,2,3]])
    # 1 2 3
    # (1, 2, 3)

    利用return 关键字可直接结束函数 # 某些场景比break还要好用些 

    # return除了可以返回值之外,还可以直接结束当前所在函数整个函数的运行,而无需像break一样,一层一层结束
    def hi():
        while True:
            name = input("what your name? >>>:")
            if name:
                print('hi, name! nice to meet you!')
            else:
                continue
            while True:
                age = input("how old are you? >>>:")
                if age:
                    print(f"oh, it hard to see that you are {age} years old!")
                else:
                    continue
                while True:
                    hobby = input("what's your hobby? >>>:")
                    if hobby:
                        print(f'you like {hobby}, it seems so cool.')
                        return  # 执行到这里,hi() 这个函数就直接结束了
    
    
    hi()

    小推理

    '''
    所有的函数都有返回值,无论你写不写return
        python中,不写返回值默认返回None,其实也算返回值
    只写return或者return None 并不是为了考虑返回值的问题,而是为了结束函数的运行
    '''

    函数的参数

    形参: # 在函数定义阶段,函数的括号内写的变量名,叫做该函数的形式参数,简称形参 

    实参: # 在函数调用阶段,括号内实际传入的值,叫做实际参数,简称实参 

    形参与实参的关系: # 形参就相当于变量名,而实参相当于变量的值,函数调用传参的过程就是给形参、变量名赋值的过程 

    注意点: # 实参和形参的绑定关系只在函数的运行阶段有效,函数运行结束后自动解除 # 只在函数内部有效,函数外部无任何影响 

    两种传参方式

    # 位置形参:在函数定义阶段按照位置从左往右依次书写的变量名
    def my_max(x, y):
        print(x, y)
        if x > y:
            return x
        else:
            return y
    # res = my_max(1)  # 会报错,在调用函数的时候 少一个实参不行
    # res = my_max(1, 2, 3)  # 会报错,在调用函数的时候 多一个实参也不行
    
    
    # 第一种直接按照位置传  一一对应
    res = my_max(20, 10)
    # 20 10
    # 位置实参:在函数的调用阶段 传入的参数会按照位置一一对应给形参
    
    # 第二种指名道姓的传  >>>:关键字传参
    my_max(y=20, x=10)
    my_max(10, y=20)  # 位置和关键字混合使用
    my_max(20, y=40)
    # 10 20
    # 10 20
    # 20 40

    注意点:

    """
    注意:在函数的调用阶段 位置参数和关键字参数可以混合使用
    但是必须保证
        1.位置参数必须在关键字参数的前面(越短的越靠前,越长的越复杂的越靠后)
        2.同一个形参不能被多次赋值
    """

    默认值参数

    默认值参数: # 在函数的定义阶段,形参(变量名)就已经被赋值了的参数 , def my_max(x,y=100): # 这里的y 就是一个默认值参数 

    def my_max(x, y=100):
        if x > y:
            return x
        return y
    print(my_max(200))  # 这里没有传入默认参数y, y 等于 默认值函数定义时的 100,y = 100
    print(my_max(200, 1000))  # 这里传入了默认参数y, y 等于 传入的 1000,y = 1000
    print(my_max(y=200, x=1000))  # 这里使用关键字传参,传了 y = 200, y = 200
    # 200
    # 1000
    # 1000
    
    '''
    # 在调用的时候可以不为默认值形参传值,默认使用定义阶段就已经绑定的值
    # 在调用的时候如果可以给默认值形参传值 传了那么就使用你传的值
    # 在定义阶段 默认值形参必须放在位置形参的后面
    '''

    默认值参数的应用场景(例如录入信息时的性别)

    student_infos = []
    def record_student_info(student_name, student_age, student_gender='male'):
        student = dict(name=student_name, age=student_age, gender=student_gender)
        student_infos.append(student)
    
    while True:
        student_name = input("请输入您的姓名>>>:").strip()
        student_age = input("请输入您的年龄>>>:").strip()
        student_gender = input("请输入您的性别>>>:").strip()
        if student_gender == 'female':
            record_student_info(student_name, student_age, student_gender)
        else:
            record_student_info(student_name, student_age)
        print(student_infos)

    默认值传参面试可能会考到

    # 这里的问题是共用了同一个列表(画一张列表的变量关系引用图就知道了)
    def info(username,hobby,l=[]):
        l.append(hobby)
        print('%s 的爱好是 %s'%(username,l))
    info('jason','study')
    info('tank','生蚝')
    info('kevin','喝腰子汤')
    info('egon','女教练')
    # jason 的爱好是 ['study']
    # tank 的爱好是 ['study', '生蚝']
    # kevin 的爱好是 ['study', '生蚝', '喝腰子汤']
    # egon 的爱好是 ['study', '生蚝', '喝腰子汤', '女教练']
    
    # 解决方法1,每次传一个空列表过去
    info('jason','study',[])
    info('tank','生蚝',[])
    info('kevin','喝腰子汤',[])
    info('egon','女教练',[])
    # jason 的爱好是 ['study']
    # tank 的爱好是 ['生蚝']
    # kevin 的爱好是 ['喝腰子汤']
    # egon 的爱好是 ['女教练']
    
    # 解决方法2,改写函数默认参数,没传就重新申请一个空列表
    def info(username,hobby,l=None):
        if l == None:
            l = []
        l.append(hobby)
        print('%s 的爱好是 %s'%(username,l))
    
    info('jason','study')
    info('tank','生蚝')
    info('kevin','喝腰子汤')
    info('egon','女教练')
    # jason 的爱好是 ['study']
    # tank 的爱好是 ['生蚝']
    # kevin 的爱好是 ['喝腰子汤']
    # egon 的爱好是 ['女教练']

    易错点**** # 函数在定义阶段 内部所使用的变量都已经初始化完毕了,不会因为调用的位置的变化 而影响到内部的值 

    m = 100
    def my_max(x, y=m):
        print(x, y)
    m = 222
    my_max(111)
    # 111 100
    
    '''
    函数在定义阶段 内部所使用的变量都已经初始化完毕了
    不会因为调用的位置的变化 而影响到内部的值(暂时可忽略)
    
    函数无论在什么地方被调用
    都会跑到函数定义阶段去执行代码
    形参中用到的值都是往函数定义阶段代码往上找
    '''

    可变长参数

    # 站在调用函数传递实参的角度  实参的个数不固定的情况 也就意味形参也不固定
    # 站在形参的角度 可以用*和**来接收多余的(溢出的)位置参数和关键字参数

    站在形参(函数定义)的角度看 * 、**

      *args # 形参中的*会将多余的(溢出的)位置实参 统一用元组的形式处理 传递给* 后面的形参名,* 在形参中只能接受多余的位置实参,不能接受关键字实参 

    def func(x, y, *z):
        print(x, y, z)  # z = (3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8)
    func(1, 2, 3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8,)
    # 1 2 (3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8)
    # func(1, 2, 1, 3, 4, 5, z=15)  # 报错,TypeError: func() got an unexpected keyword argument 'z'

      **kwargs # ** 会接收所有多余的关键字参数 并将关键字参数 转换成字典的形式 字典的key就是关键字的名字,字典的value就是关键字的名字指向的值 将字典交给** 后面的变量名 

    def func(x, y, **z):
        print(x,y,z)  # 去掉前面关键字传参成功的x, y,将剩下的关键字传参存入z 中, z = {'z': 1, 'a': 1, 'b': 2, 'c': 3}
    func(x=1, y=2, z=1, a=1, b=2, c=3)
    # 1 2 {'z': 1, 'a': 1, 'b': 2, 'c': 3}

    站在实参(函数调用)的角度看 * 、**

      *args # 会将容器类型(列表、元组、集合,字典不能)打散成位置实参一一传入, * 内部可以看成for 循环 

    def func(x,y,z):
        print(x,y,z)
    # l = [1,2,3]
    # a,b,c = l
    # func(a,b,c)
    func(*[1,2,3])  # * 会将列表打散成位置实参一一传入等价于func(1,2,3)
    func(*(1,2,3))  # 等价于func(1,2,3)
    # 1 2 3
    # 1 2 3
    
    def func(x,*z):
        print(x,z)
    func(1,*{1,2,3})  # * 在形参中只能接收多余的位置实参 不能接收关键字实参
    # 1 (1, 2, 3)

      **kwargs # ** 会将字典拆封成key = value的形式,以关键字传参的方式传值 

    def func(x, y, z):
        print(x, y, z)
    func(x=1, y=2, z=3)
    # 1 2 3
    d = {'x': 1, 'y': 2, 'z': 333}
    func(**d)  # 等价于func(x=1,y=2,z=333)
    # 1 2 333

    可接收任意参数的函数

    # 需求:你写的函数 无论调用者按照正确传参的方式无论怎么传 你的函数都能够正常执行
    def func1(*x, **y):
        print(x, y)
    func1(1, 2, 3, 4, 5, 6, x=1, y=2, z=3)
    # (1, 2, 3, 4, 5, 6) {'x': 1, 'y': 2, 'z': 3}
    
    """
    下面是python推荐形参*和**通用的写法(后面的参数名命名推荐)
    """
    def func2(*args, **kwargs):  # 可接收任意参数的函数
        print(args, kwargs)
    func2(1, 2, 3, 4, 5, 6, x=1, y=2, z=3)
    # (1, 2, 3, 4, 5, 6) {'x': 1, 'y': 2, 'z': 3}

    命名关键字参数

    命名关键字参数: # 在函数定义阶段,写在 * 与 ** 之间的参数 

      下面的z 和 m 都是命名关键字参数

    def func(x, y=1, *args, z=3, m, **kwargs):
        print(x, y)
        print(args)
        print(z, m)
        print(kwargs)
    
    
    func(1, 2, 3, 4, [5, 6, 7], m=1, z=3, n=1, q=1, p=2)  # 关键字传参 m = 2
    # 要想给m传值, 必须用关键字传值 m = 2,如果直接用位置参数,显然会被 *args接收(截取)
    # 调用 func() 返回值如下:
    # 1 2
    # (3, 4, [5, 6, 7])
    # 3 1
    # {'n': 1, 'q': 1, 'p': 2}

    注意: # 在给命名关键字参数传值的时候 只能用关键字为其传值 , # 在定义阶段 给你感觉好像是z是默认值参数 放在了m这个位置参数的前面了 应该报错,但其实 z 和 m 都不是默认值参数和位置参数, 他们是命名关键字参数 

    函数的注释

    函数注释的好处: # 规范的代码注释可以让封装的方法被快速读懂,让调用者快速上手....(有着诸多好处) 

    # 在pycharm 中只需要在函数定义def 关键字下一行 敲 ''' 回车即可自动出现函数注释格式,只需相应填充即可
    """
    该函数的作用
    :param x: 对形参x的解释
    :param y: 对形参y的解释
    :return: 对函数返回值的解释
    """

    查看写好的函数注释: # help(函数名) ,会返回该函数的注释信息

    def say_hi(name):
        '''
        跟用户打招呼
        :param name: 用户名
        :return: 拼接好的打招呼语句
        '''
        hi = '{name} 你好,很高兴见到你!'.format(name=name)
        return hi
    
    
    print(help(say_hi))
    # Help on function say_hi in module __main__:
    # 
    # say_hi(name)
    #     跟用户打招呼
    #     :param name: 用户名
    #     :return: 拼接好的打招呼语句
    # 
    # None

    上面介绍了函数的return返回值、参数、注释, 下面给出一个标准的函数定义格式

    """
    def 函数名(形参1, ......):
        '''
        该函数的作用(函数的注释)
        :param 形参1: 对形参1的解释
        :param .....: .....
        :return: 
        '''
        代码体
        return 函数的返回值
    """
  • 相关阅读:
    JAVA并发-CountDownLatch
    【转载】Makedown数学公式语法
    算法的时间复杂度
    JVM-卡表(Card Table)
    sync.WaitGroup的使用以及坑
    go 多协程爬取图片
    go ioutial 读取写入文件
    go 下载图片
    go 正则 爬取邮箱代码
    go 解析path
  • 原文地址:https://www.cnblogs.com/suwanbin/p/11152151.html
Copyright © 2011-2022 走看看