zoukankan      html  css  js  c++  java
  • Day3_1-函数

    一、为什么要用函数

    #1、代码的组织结构不清晰,可读性差
    
    #2、遇到重复的功能只能重复编写实现代码,代码冗余
    
    #3、功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大 

    二、函数是什么

    想象生活中的例子,修理工需要实现准备好工具箱里面放好锤子,扳手,钳子等工具,然后遇到锤钉子的场景,拿来锤子用就可以,而无需临时再制造一把锤子。
    
    修理工===>程序员
    具备某一功能的工具===>函数
    
    要想使用工具,需要事先准备好,然后拿来就用且可以重复使用
    要想用函数,需要先定义,再使用

    三、函数的分类

    #1、内置函数
    为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()
    
    #2、自定义函数
    很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。

    四、如何定义一个函数

    #语法
    def 函数名(参数1,参数2,参数3,...):
        '''注释'''
        函数体
        return 返回的值
    
    #函数名要能反映其意义

    4.1 实操

    def tell_tag():
        print('===========')
    
    def tell_msg(msg):
        print(msg)
    
    
    #调用阶段
    tell_tag()
    tell_tag()
    tell_msg('hello world')
    tell_tag()
    tell_tag()
    # func()
    
    print(tell_msg)
    
    '''
    ===========
    ===========
    hello world
    ===========
    ===========
    
    '''

    五、函数使用的原则:先定义,再调用

    5.1 实操

    #1.函数的使用必须遵循:先定义,后调用
    #2.函数的定义,就相当于在定义一个变量,如果没有定义而直接调用,就相当于在引用一个不存在的变量名
    
    # #定义阶段
    # def foo():
    #     print('from foo')
    #     bar()
    #
    # #调用阶段
    # foo()
    
    # #定义阶段
    # def bar():
    #     print('from bar')
    # def foo():
    #     print('from foo')
    #     bar()
    #
    # #调用阶段
    # foo()
    
    #定义阶段
    def foo():
        print('from foo')
        bar()
    
    def bar():
        print('from bar')
    #调用阶段
    foo()

    六、函数在定义阶段都干了哪些事

    #只检测语法,不执行代码
    也就说,语法错误在函数定义阶段就会检测出来,而代码的逻辑错误只有在执行时才会知道

    6.1 实操

    #函数在定义阶段,只检测语法,不执行代码
    def func():
        print('aaaaaa')
        xxxxx
        yyyy
        zzssaa
        asdfasdfasdfasdf
        # if
        # print('asdfasdfasfd'
    
    func()

    七、定义函数的三种形式

    #1、无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印
    #2、有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值
    #3、空函数:设计代码结构
    #结论:
    #1、定义时无参,意味着调用时也无需传入参数
    #2、定义时有参,意味着调用时则必须传入参数

    八、调用函数

    函数的调用:函数名加括号
    1 先找到名字
    2 根据名字调用代码

    8.1 函数返回值

    无return->None
    return 1个值->返回1个值
    return 逗号分隔多个值->元组
    
    什么时候该有返回值?
        调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
        通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
    什么时候不需要有返回值?
        调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
        通常无参函数不需要有返回值

    8.2 实操

    #1 调用函数:函数名(),
    #需要注意:先通过名字找到函数的内存地址,然后加括号调用
    
    #2 函数的返回值return
    #注意的第一点:
    #在调用函数的过程中,一旦执行到return,就会立刻终止函数,并且把return后的结果当做本次调用的返回值返回
    #函数体内可以有多个return,但是只能执行一次
    # def foo():
    #     print('111')
    #     return 1
    #     print('2222')
    #     return 2
    #     print('3333')
    #     return 3
    #
    # res=foo()
    # print('函数调用完毕',res)
    
    #注意的第二点:
    #返回的值,可以是任意类型
    
    #注意的第三点:
    
    #没有return:默认返回None
    #可以返回一个值===>值
    #可以用逗号分隔,返回多个值===>tuple
    # def foo():
    #     return None
    #
    # res=foo()
    # print('函数调用完毕',res,type(res))
    
    #3:调用函数的三种形式
    
    def foo():
        print('from foo')
        return 123
    
    # foo()
    
    # res=foo()
    # print(res)
    
    res=foo()*10
    print(res)

    九、函数的参数

    形参与实参

    #形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定

    9.1 实操

    #形参:在定义函数时,括号内的参数成为形参
    #特点:形参就是变量名
    # def foo(x,y): #x=1,y=2
    #     print(x)
    #     print(y)
    
    #实参:在调用函数时,括号内的参数成为实参
    #特点:实参就是变量值
    # foo(1,2)
    
    #在调用阶段实参(变量值)才会绑定形参(变量名)
    #调用结束后,解除绑定
    
    #参数的分类
    #位置参数:按照从左到右的顺序依次定义的参数
        #位置形参:必须被传值,并且多一个不行,少一个也不行
        #位置实参:与形参按照位置一一对应
    
    # def foo(x,y):
    #     print(x)
    #     print(y)
    #
    # foo('egon',1,2)
    
    #关键字实参:指的是按照name=value的形式,指名道姓地给name传值
    # def foo(name,age):
    #     print(name)
    #     print(age)
    
    # foo('egon',18)
    # foo(age=18,name='egon')
    
    #关键字实参需要注意的问题是:
    # def foo(name,age,sex):
    #     print(name)
    #     print(age)
    #     print(sex)
    
    # foo('egon',18,'male')
    # print('======>')
    # foo(sex='male',age=18,name='egon')
    # foo('egon',sex='male',age=18)
    
    #问题一:语法规定位置实参必须在关键字实参的前面
    # foo('egon',sex='male',age=18)
    
    #问题二:一定不要对同一个形参传多次值
    # foo('egon',sex='male',age=18,name='egon1')
    
    # foo('male',age=18,name='egon1')
    
    #默认形参:在定义阶段,就已经为形参赋值,意味在调用阶段可以不用传值
    # def foo(x,y=1111111):
    #     print(x)
    #     print(y)
    #
    # foo(1,'a')
    #
    # def register(name,age,sex='male'):
    #     print(name,age,sex)
    #
    # register('asb',73)
    # register('wsb',38)
    # register('ysb',84)
    # register('yaya',28,'female')
    
    #默认参数需要注意的问题
    #问题一:默认参数必须放在位置参数之后
    # def foo(y=1,x):
    #     print(x,y)
    
    #问题二:默认参数只在定义阶段赋值一次,而且仅一次
    # x=100
    # def foo(a,b=x):
    #     print(a,b)
    #
    # x=111111111111111111111111111111
    # foo('egon')
    
    #问题三:默认参数的值应该定义成不可变类型

     9.2 具体应用

    #1、位置参数:按照从左到右的顺序定义的参数
            位置形参:必选参数
            位置实参:按照位置给形参传值
    
    #2、关键字参数:按照key=value的形式定义的实参
            无需按照位置为形参传值
            注意的问题:
                    1. 关键字实参必须在位置实参右面
                    2. 对同一个形参不能重复传值
    
    #3、默认参数:形参在定义时就已经为其赋值
            可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
            注意的问题:
                    1. 只在定义时赋值一次
                    2. 默认参数的定义应该在位置形参右面
                    3. 默认参数通常应该定义成不可变类型
    
    
    #4、可变长参数:
            可变长指的是实参值的个数不固定
            而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs
    
            ===========*args===========
            def foo(x,y,*args):
                print(x,y)
                print(args)
            foo(1,2,3,4,5)
    
            def foo(x,y,*args):
                print(x,y)
                print(args)
            foo(1,2,*[3,4,5])
    
    
            def foo(x,y,z):
                print(x,y,z)
            foo(*[1,2,3])
    
            ===========**kwargs===========
            def foo(x,y,**kwargs):
                print(x,y)
                print(kwargs)
            foo(1,y=2,a=1,b=2,c=3)
    
            def foo(x,y,**kwargs):
                print(x,y)
                print(kwargs)
            foo(1,y=2,**{'a':1,'b':2,'c':3})
    
    
            def foo(x,y,z):
                print(x,y,z)
            foo(**{'z':1,'x':2,'y':3})
    
            ===========*args+**kwargs===========
    
            def foo(x,y):
                print(x,y)
    
            def wrapper(*args,**kwargs):
                print('====>')
                foo(*args,**kwargs)
    
    #5、命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
    可以保证,传入的参数中一定包含某些关键字
            def foo(x,y,*args,a=1,b,**kwargs):
                print(x,y)
                print(args)
                print(a)
                print(b)
                print(kwargs)
    
            foo(1,2,3,4,5,b=3,c=4,d=5)
            结果:
                1
                2
                (3, 4, 5)
                1
                3
                {'c': 4, 'd': 5}

    9.3 实操

    #1:形参与实参
    #形参:在函数定义阶段,括号内定义的参数的称为形参,就相当于变量名
    #实参:在函数调用阶段,括号内定义的参数的称为实参,就相当于变量值
    
    #在调用阶段,实参的值会绑定给形参,在调用结束后,解除绑定
    
    
    # def foo(x,y): #x=1,y=2
    #     print(x,y)
    #
    # foo(1,2)
    
    #参数的分类:
    '''
    一:位置参数
        位置形参:必须被传值的参数,多一个不行,少一个也不行
        位置实参:从左到右依次赋值给形参
    
    '''
    # def foo(x,y):
    #     print(x,y)
    #
    # foo(1,2)
    
    
    '''
    二:关键字参数:在函数调用阶段,按照key=value的形式定义实参
        可以不依赖位置而指名道姓地给形参传值
        需要注意的问题(可以与位置实参混用,但是):
            1. 位置实参必须在关键字实参的前面
            2. 不能为一个形参重传值
    '''
    # def foo(x,y):
    #     print(x,y)
    #
    # foo(1,2,y=20)
    
    
    '''
    三:默认参数:在定义函数阶段,已经为形参赋值了,在定义阶段已经赋值,意味着在调用阶段
    可以不传值
        注意的问题:
            1 默认参数的值,只在定义时赋值一次
            2 位置形参应该在默认参数的前面
            3 默认参数的值应该是不可变类型
    
    '''
    # def foo(x,y=10):
    #     print(x,y)
    #
    #
    # foo(y=11,x=1)
    
    
    # def register(name,age,sex='male'):
    #     print(name,age,sex)
    #
    #
    # register('egon',18)
    # register('wsb',18)
    # register('alex',38,'xxxxxx')
    
    
    
    # x='male'
    # def register(name,age,sex=x):
    #     print(name,age,sex)
    #
    # x='female'
    # register('alex',18)
    
    #
    # def register(name,sex='male',age):
    #     print(name,age,sex)
    '''

    9.4 实操二

    可变长参数
    
    实参可变长度指的是:实参值的个数是不固定
    而实参的定义形式无非两种:1、位置实参,2、关键字实参
    针对这两种形式的实参个数不固定,相应的,形参也要有两种解决方案
    *
    **
    
    
    '''
    
    #针对按照位置定义的溢出的那部门实参,形参:*args
    # def func(x,y,z,*args): #args=(4,5,6)
    #     print(x,y,z)
    #     print(args)
    #
    # func(1,2,3)
    # func(1,2,3,4,5,6)
    # func(1,2,3,*[4,5,6]) #func(1,2,3,4,5,6)
    # func(*[1,2,3,4,5,6]) #func(1,2,3,4,5,6)
    
    # func([1,2,3,4,5,6]) #func(1,2,3,4,5,6)
    
    
    # def func(x,y,z):
    #     print(x,y,z)
    #
    # l=[1,2,3]
    # func(*l)
    
    #针对按照关键字定义的溢出的那部分实参,形参:**kwargs
    # def foo(x,y,**kwargs): #kwargs={'a':1,'z':3,'b':2}
    #     print(x,y)
    #     print(kwargs)
    
    # foo(y=2,x=1,z=3,a=1,b=2)
    # foo(1,2,3,z=3,a=1,b=2)
    
    # foo(y=1,x=2,**{'a':1,'b':2,'c':3}) #foo(x=2,y=1,c=3,b=2,a=1)
    # foo(**{'x':1,'a':1,'b':2,'c':3}) #foo(x=1,c=3,b=2,a=1)
    
    # def foo(x,y,z):
    #     print(x,y,z)
    #
    # dic={'x':1,'y':3,'z':1}
    # foo(**dic)  #foo(x=1,y=3,a=1)
    
    
    #
    # def home(name,age,sex):
    #     print('from home====>',name,age,sex)
    #
    # def wrapper(*args,**kwargs): #args=(1,2,3,4,5,6,7),kwargs={'c':3,'b':2,'a':1}
    #     home(*args,**kwargs)
    #     # home(*(1,2,3,4,5,6,7),**{'c':3,'b':2,'a':1})
    #     #home(1,2,3,4,5,7,a=1,b=2,c=3)
    #
    #
    #
    # # wrapper(1,2,3,4,5,6,7,a=1,b=2,c=3)
    # wrapper('egon',sex='male',age=19)
    
    #五:命名关键字参数(了解):
    # 形参中,在*后定义的参数称之为命名关键字参数,
    # 它的特性是;传值时,必须按照关键字实参的形式传值
    # def foo(x,y=20,*args,a=1,b):
    #     print(x,y,a,b)
    
    # # foo(10,b=3)
    # foo(10,22,33,44,a=2,b=3)
    
    
    # 位置参数,默认参数,*args,命名关键字参数,**kwargs

    十、函数对象

    10.1 实操

    #函数是第一类对象:函数可以当做数据来使用
    def foo():
        print('from foo')
    
    #可以被引用
    # f=foo
    # # print(f)
    # f()
    
    #可以当做参数传入一个函数
    # def wrapper(x):
    #     # print(x)
    #     x()
    # wrapper(foo)
    
    #可以当做函数的返回值
    # def wrapper():
    #     return foo
    #
    # f=wrapper()
    # print(f is foo)
    
    #可以当做容器类型的一个元素
    
    # l=[foo,1,2]
    # l[0]()
    
    data_dir='/usr/local/mysql/data'
    def select(sql):
        print('select功能: ',sql)
    
    def insert(sql):
        print('insert功能: ', sql)
    
    def update(sql):
        print('update功能: ', sql)
    
    def delete(sql):
        print('delete功能: ', sql)
    
    def alter(sql):
        print('alter功能:',sql)
    
    func_dic={
        'select':select,
        'update':update,
        'insert':insert,
        'delete':delete,
        'alter':alter
    }
    
    def main():
        while True:
            inp=input('>>: ').strip()
            if not inp:continue
            sql=inp.split()
            cmd=sql[0]
            # if cmd == 'select':
            #     select(sql)
            # elif cmd == 'update':
            #     update(sql)
            # elif cmd == 'insert':
            #     insert(sql)
            # elif cmd == 'delete':
            #     delete(sql)
            if cmd in func_dic:
                func_dic[cmd](sql)
            else:
                print('command not found')
    
    main()

    十一、函数嵌套

    11.1 实操

    #1 函数的嵌套调用:在调用一个函数的过程中,又调用其他的函数
    # def my_max2(x,y):
    #     if x > y:
    #         return x
    #     else:
    #         return y
    #
    #
    # def my_max4(a,b,c,d):
    #     res1=my_max2(a,b)
    #     res2=my_max2(res1,c)
    #     res3=my_max2(res2,d)
    #     return res3
    #
    # res=my_max4(1,2,3,4)
    # print(res)
    
    #2 函数的嵌套定义:在定义一个函数内部,又定义了一个函数
    def f1():
        def f2():
            def f3():
                print('from f3')
            f3()
        x=1
        f2()
        print(x)
    f1()
    
    # f2()
    # print(x)

    作者:大雄猫
    出处:http://www.cnblogs.com/guoxiangqian/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面 明显位M给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    读书笔记_Effective_C++_条款二:尽量以const, enum, inline替换#define
    读书笔记_代码大全_第14章_组织直线型代码_第15章_使用条件语句
    读书笔记_代码大全_第31章_布局与风格
    读书笔记_代码大全_第16章_控制循环
    读书笔记_Effective_C++_条款五:了解C++默默编写并调用哪些函数
    python学习笔记(三)——字符串
    python学习笔记(六)——函数
    Windows下安装Django
    python小专题——time模块
    python学习笔记(四)——数据字典
  • 原文地址:https://www.cnblogs.com/guoxiangqian/p/7562914.html
Copyright © 2011-2022 走看看