zoukankan      html  css  js  c++  java
  • Python学习-函数初识、函数参数使用

    记录下python中函数的使用入门,函数就相当于java中的方法,想法都是减少重复代码,将公共部分抽取出来并可反复调用,只是用法有些差别。

    函数初识

    假如python中没有len方法,如果需要计算字符串字符个数,或者列表长度,可以分别用如下方式实现。

    如计算字符串长度。

    s='hgoahgohgohgogog'
    # 假设python没有len方法,如何计算上面字符串的字符个数?
    count=0
    for item in s:
        count+=1
    print(count)
    

    如计算列表长度。

    li=[1,2,3,4,5,6]
    # 假设python没有len方法,如何计算上面列表的元素个数?
    count=0
    for item in li:
        count+=1
    print(count)
    

    可以看出,上面的逻辑一样,这时函数的想法呼之欲出,python中的函数就是java中的方法的意思,上面的逻辑可以使用函数实现,使用def关键字定义函数。

    def my_len(x):
        count = 0
        for item in x:
            count += 1
        print(count)
    

    函数名需要见名知意,函数体中尽量不要写print打印东西。需要注意的是,如果函数中有return关键字,后面的代码将不再执行。

    def meet(str):
        print('打开'+str)
        print('出来了很多小姐姐')
        # 函数中有return,后面的代码不执行
        return
        print('怀着屌丝的心态浏览了下')
        print('10分钟后')
        print('我好了')
        # 可以返回结果
        return '别做梦了'
    # 调用  
    ret=meet('探探')
    print(ret)
    

    执行结果可以看出,return后面的代码将不再执行。

    打开探探
    出来了很多小姐姐
    None
    

    返回值只有单个的话,数据是什么类型返回后就是什么类型,如果函数使用return返回值有多个值,将以元祖形式返回给函数的执行者。

    def test():
        return 'messi',123,[1,2,3]
    
    print(test(),type(test())) # ('messi', 123, [1, 2, 3]) <class 'tuple'>
    

    总结一下,return在函数中使用,效果如下。

    1. return 可以终止函数,后面的代码不再执行。
    2. return 单个值,是什么类型就返回什么类型 。
    3. return 多个值,以元祖形式返回。

    函数的参数

    函数的参数分为实参和形参,如下函数执行传递的参数(男、女、人妖)是实际参数,函数定义里的那个参数(sex)就是形参。

    # sex为形参
    def my_print(sex):
        print('我的性别是%s' % (sex))
    # 传入实参
    my_print('男')
    my_print('女')
    my_print('人妖')
    

    函数参数的使用,可以分别从实参角度,形参角度来说明,最后参数使用中会混合位置参数、默认参数、还有其他形式的参数,如何正确的使用也记录一下。

    实参角度

    (1)位置传参

    位置传参就是传入的实际参数位置需要和形参一一对应,不能顺序错误。

    # 实参和形参,从左至右,一一对应
    def data_print(sex, age, hobby):
        print('我的性别是%s,年龄是%s,爱好是%s' % (sex, age, hobby))
    
    data_print('男', '33', '女') # 我的性别是男,年龄是33,爱好是女
    

    使用三元运算符比较数字大小,520传入a的位置,1314传入b的位置。

    # 三元运算符
    def my_max_2(a, b):
        return a if a > b else b
    
    print(my_max_2(520, 1314)) # 1314
    

    (2)关键字参数

    关键字参数,需使用'形参参数名=传递参数值'指定好了形参的值,关键字参数的顺序不需要和形参保持一致,但是如果还有位置参数,需要放在关键字参数的前面。

    data_print(sex='人妖', hobby='男', age=45) # 我的性别是人妖,年龄是45,爱好是男
    

    (3)混合传参

    既有位置参数,又有关键字参数的情况,位置参数一定要在关键字参数的前面,否则报错。

    data_print('男', hobby='足球', age=45) # 我的性别是男,年龄是45,爱好是足球
    

    如果位置参数不在关键字参数前面,会报错提示。

    data_print(hobby='足球', age=45,'男')
    # 报错
    SyntaxError: positional argument follows keyword argument
    

    总结一下实参角度的参数使用,如下。

    1. 位置参数:需要和形参顺序一一对应。
    2. 关键字参数:顺序不一定,但是要一一对应。
    3. 混合参数:位置参数一定要在关键字参数的前面。

    形参角度(*args **kwargs)

    (1)位置参数

    形参角度的位置参数同上,练习传入一个列表,如果列表的长度大于2,那么仅仅保留前两个长度的内容返回。

    # 不管长度是否大于2,切片都可以使用
    def get_list_3(li):
        return li[0:2]
    

    (2)默认参数

    可以在形参中定义默认参数,默认参数需要定义在参数后面。

    #年龄默认25
    def data_print_2(sex, hobby, age=25):
        print('我的性别是%s,年龄是%s,爱好是%s' % (sex, age, hobby))
    
    data_print_2('男', '足球') # 我的性别是男,年龄是25,爱好是足球
    # 如果传入age,则覆盖默认值
    data_print_2('男', '足球', age=45) # 我的性别是男,年龄是45,爱好是足球
    

    (3)*args

    args是arguments的简写,表示位置参数。使用星号在函数定义时代表聚合,*args代表将可变参数聚合成一个元祖,将结果传递给函数实参。

    def my_print(*args):
        print(type(args)) 
        print('天皇巨星:%s,%s,%s,%s' % args) 
        
    my_print('messi', 'ronald', 'herry', 'kaka')
    
    # 执行结果
    # <class 'tuple'>
    # 天皇巨星:messi,ronald,herry,kaka
    

    (4)**kwargs

    kwargs是keyword arguments的缩写,表示关键字参数。**kwargs是聚合关键字参数为一个字典,存储到kwargs中传递给函数实参。

    def test(**kwargs):
        print(kwargs)
    # 打印结果为字典
    test(name='clyang',age=28,hobby='football') # {'name': 'clyang', 'age': 28, 'hobby': 'football'}
    

    使用*args和**kwargs可以接收任意类型的参数。

    # 位置参数,被*args接收,关键字参数,被**kwargs接收
    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    # 测试传入位置参数和关键字参数
    func(1,2,3,name='messi',age=34,score=33) 
    
    # 输出结果
    # (1, 2, 3)
    # {'name': 'messi', 'age': 34, 'score': 33}
    

    形参角度的参数顺序

    形参角度的参数使用,包括位置参数、默认参数、*args、**kwargs、仅限关键字参数。

    (1)位置参数、默认参数、args一起使用时,顺序为位置参数、args、默认参数。

    def sequence(a,b,*args,c='男'):
        print(a,b)
        print(c)
        print(args)
    
    sequence(1,2,3,4,5) 
    sequence(1,2,3,4,5,c='人妖')
    

    输出结果可以看出,a和b分别接收了1和2,*args接收了后面的三个参数3、4、5形成元祖。

    1 2
    男
    (3, 4, 5)
    
    1 2
    人妖
    (3, 4, 5)
    

    (2)位置参数、默认参数、args、**kwargs一起使用时,顺序为位置参数、args、默认参数、**kwargs。

    def sequence_2(a,b,*args,c='男',**kwargs):
        print(a, b)
        print(c)
        print(args)
        print(kwargs)
    
    sequence_2(1,2,3,4,5,name='messi',age=28)
    sequence_2(1,2,3,4,5,name='messi',age=28,c='女')
    sequence_2(1,2,3,4,5,c='人妖',name='messi',age=28)
    

    输出结果,a和b分别接收了1和2,*args接收了后面的三个参数3、4、5形成元祖,**kwargs接收关键字参数形成字典。

    1 2
    男
    (3, 4, 5)
    {'name': 'messi', 'age': 28}
    
    1 2
    女
    (3, 4, 5)
    {'name': 'messi', 'age': 28}
    
    1 2
    人妖
    (3, 4, 5)
    {'name': 'messi', 'age': 28}
    

    (3)仅限关键字参数

    处于*args和**kwargs之间的参数,就是仅限关键字参数。

    def sequence_3(a,b,*args,c='男',d,**kwargs):
        print(a, b)
        print(c)
        print(d)
        print(args)
        print(kwargs)
    
    sequence_3(1,2,3,4,5,name='messi',age=28,d='仅限关键字参数')
    

    输出结果,a和b分别接收了1和2,*args接收了后面的三个参数3、4、5形成元祖,**kwargs接收关键字参数形成字典,d接收'仅限关键字参数'。d这个参数位置可以看出,它不可能是位置参数,只能在调用的时候赋予值变成仅限关键字参数。

    1 2
    男
    仅限关键字参数
    (3, 4, 5)
    {'name': 'messi', 'age': 28}
    

    行参的参数最终顺序为:位置参数、*args、默认参数、仅限关键字参数、**kwargs,其中默认参数和仅限关键字参数位置可以互换。

    '*'和'**'

    *或**,在函数定义时,代表聚合,而在函数使用时,代表打散。

    def func_2(*args):
        print(args)
    
    func_2([1,2],[3,4]) # ([1, 2], [3, 4])
    func_2(*[1,2],*[3,4]) # 等效func_2(1, 2, 3, 4),结果为(1, 2, 3, 4)
    func_2(1, 2, 3, 4) # (1, 2, 3, 4)
    
    def func_3(**kwargs):
        print(kwargs)
    
    func_3(name='messi',age=28) # {'name': 'messi', 'age': 28}
    func_3(**{'name':'messi'},**{'age':28}) # 等效func_3(name='messi',age=28)
    
    

    函数练习

    函数练习主要还是复习前面知识点为主,只是套了一个函数的外壳,体会函数。

    (1)写一个函数,传入一个字典,判断字典里value的长度,如果value长度大于2,只保留前两个长度的内容,将新的结果返回。

    def get_new_dict(dic):
        new_dic = {}
        for key in dic:
            new_dic[key] = dic.get(key)[0:2]
        return new_dic
    
    print(get_new_dict({'name': 'haaaa', 'hobby': 'football', 'score': 'many'})) # {'name': 'ha', 'hobby': 'fo', 'score': 'ma'}
    

    (2)写一个函数,此函数值接受一个参数并且参数类型必须是列表类型,此函数完成的功能是返回调用者一个字典,键值对分别是列表元素的索引-元素值,如传入['messi','ronald','herry','kaka'],返回{1:'messi',2:'ronald',3:'herry',4:'kaka'}。

    def get_dict_from_list(li):
        # if type(li) == type([]):
        if isinstance(li, list):
            dic = {}
            for index in range(len(li)):
                dic[index] = li[index]
            return dic
        else:
            return '错误的数据类型'
    
    
    print(get_dict_from_list(['messi', 'ronald', 'herry'])) # {0: 'messi', 1: 'ronald', 2: 'herry'}
    print(get_dict_from_list('haha')) # 错误的数据类型
    

    (3)写一个函数,接受四个参数分别是:姓名、性别、年龄、学历。用户输入这个四个内容,传入到函数后,函数接受到这四个内容,将内容追加到一个文件中。支持用户持续输入,按Q或者q退出,性别默认是男,如果用户输入女,则性别更换为女。

    def append_to_file(name, age, background, gender='男'):
        with open('student_info.txt', encoding='utf-8', mode='a') as f1:
            f1.write('{}	{}	{}	{}
    '.format(name, gender, age, background))
    
    
    while 1:
        str = input('请输入姓名,性别,年龄,学历,按空格隔开')
        if str.upper() == 'Q': break
        if len(str.split()) != 4:
            print('输入信息不是4个')
        else:
            li = str.split()
            if li[2].isdecimal():
                name = li[0]
                gender = li[1]
                age = int(li[2])
                background = li[3]
                # 调用函数
                if gender == '女':
                    append_to_file(name, age, background, gender)
                else:
                    append_to_file(name, age, background)
            else:
                print('输入年龄格式错误,请重新全部输入')
    

    (4)写函数,用户传入修改的文件名,与要修改的内容,执行函数完成整个文件批量的修改操作。

    import os
    def modify_file(filepath,old,new):
        with open(filepath, encoding='utf-8', mode='r') as f1, 
                open(filepath+'_bak', encoding='utf-8', mode='w') as f2:
            for line in f1:
                # 读一行,修改一行
                new_line=line.replace(old,new)
                # 修改一行,写一行
                f2.write(new_line)
        # 删除旧文件
        os.remove(filepath)
        # 重命名新文件
        os.rename(filepath+'_bak',filepath)
    
    modify_file('文件的修改.txt','clyang','超哥')
    

    PS:以上,理解不一定正确,学习就是一个不断认识和纠错的过程,如果有误还请批评指正。

    参考博文:

    (1)https://www.jianshu.com/p/0ed914608a2c *args **kwargs

    (2)https://www.cnblogs.com/scofi/p/4920989.html 位置参数

  • 相关阅读:
    WordPress主题开发实例:查询单篇文章
    WordPress基础:get_page_link获取页面地址
    WordPress主题开发:优化标题
    React中的的JSX
    WordPress主题开发:WP_Query常用参数
    WordPress基础:wp_list_pages显示页面信息列表
    WordPress基础:常用分类列表wp_list_categories
    SQL Server 2008 安装教程
    XCODE调试时不显示变量值/指针地址的解决方案
    android iOS 编码问题害死人!
  • 原文地址:https://www.cnblogs.com/youngchaolin/p/15112512.html
Copyright © 2011-2022 走看看