zoukankan      html  css  js  c++  java
  • python中的函数、变量和递归函数

    一、函数的定义

            初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数。自变量x的取值范围叫做这个函数的定义域

    例如y=2*x

    python中函数定义:函数是逻辑结构化和过程化的一种编程方法。

     1 python中函数定义方法:
     2  
     3 def test(x):
     4     "The function definitions"
     5     x+=1
     6     return x
     7      
     8 def:定义函数的关键字
     9 test:函数名
    10 ():内可定义形参
    11 "":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
    12 x+=1:泛指代码块或程序处理逻辑
    13 return:定义返回值
    14 
    15 
    16 调用运行:可以带参数也可以不带,根据定义时括号内是否有参数来决定
    17 函数名()

    例:

    #定义函数
    def test(x):
        y = 2 * x + 1
        return y
    
    #调用函数
    print(test)
    test(3)         ##调用函数但是return的值没有接收,返回的是test函数的内存地址
    a = test(2)     ##使用变量a接收函数的返回值
    print(a)

    输出:

    注意:当函数出现重名时,调用时后边的函数会覆盖掉之前的函数,因为python语言从上到下依次解释执行

               return 不能出现多个,代码执行时碰到第一个return就会结束

    例:

    #定义函数
    def test(x):
        y = 2 * x + 1
        return y
    
    def test( ):
        x = 2
        y = x + 1
        return y
    
    #调用函数
    a = test()     
    #b = test(2)    ##会报错
    print(a)

    二、为什么要有函数

    通过下面实现同一功能的两块代码对比,就可以看出在某些合适的生产场景下使用函数的好处:

    代码1:
     while True:
          if cpu利用率 > 90%:
              #发送邮件提醒
              连接邮箱服务器
              发送邮件
              关闭连接
           
          if 硬盘使用空间 > 90%:
              #发送邮件提醒
              连接邮箱服务器
              发送邮件
              关闭连接
          
          if 内存占用 > 80%:
              #发送邮件提醒
              连接邮箱服务器
              发送邮件
              关闭连接
    
    代码2:
    def 发送邮件(内容)
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接
         
    while True:
         
        if cpu利用率 > 90%:
            发送邮件('CPU报警')
         
        if 硬盘使用空间 > 90%:
            发送邮件('硬盘报警')
         
        if 内存占用 > 80%:
            发送邮件('内存报警')

     使用函数的好处

    1.代码重用(减少冗余,提高代码的有效性)

    2.保持一致性,易维护

    3.可扩展性

    三、函数和过程

    过程定义:过程就是简单特殊没有返回值的函数,即没有return,返回值为None

    这么看来我们在讨论为何使用函数的的时候引入的函数,都没有返回值,没有返回值就是过程,没错,但是在python中有比较神奇的事情

    # 无返回值,为过程
    def test01():
        msg = 'hello The little green frog'
        print(msg)
    
    
    # 有返回值,为函数
    def test02():
        msg = 'hello WuDaLang'
        print(msg)
        return msg
    
    
    t1 = test01()
    
    t2 = test02()
    
    print ('from test01 return is %s' %t1)    ##返回值为None
    print ('from test02 return is %s' %t2)

    输出:

    总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,

    所以在python中即便是过程也可以算作函数。

    def test01():
        pass
    def test02():
        return 0
    
    def test03():
        return 0,10,'hello',['alex','lb'],{'WuDaLang':'lb'}
    
    t1=test01()
    t2=test02()
    t3=test03()
    
    
    print('from test01 return is [%s]: ' %type(t1),t1)
    print('from test02 return is [%s]: ' %type(t2),t2)
    print('from test03 return is [%s]: ' %type(t3),t3)    ##当返回值为多个时,会将这几个值组成一个元组返回

    输出:

    总结:

       返回值数=0:返回None

       返回值数=1:返回object

       返回值数>1:返回tuple

    四、函数中的参数

    1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元,也就是说形参不占用内存空间(变量亦是如此,不会占用内存空间,只有真正的数据类型才会占用内存空间)。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

    2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

     

    3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)

    • 位置参数(必须一一对应)
    def test(x,y,z):
        print(x)
        print(y)
        print(z)
    
    test(1,2)   ##x=1,y=2,没有给z赋值,会报错

    输出:

    • 关键字参数(位置不用固定,但是个数不能少)
    def test(x,y,z):
        print(x)
        print(y)
        print(z)
    
    test(y=1,z=2,x=5)

    输出:

    • 位置参数与关键字参数的混合使用(位置参数必须在关键字参数的左边)
    def test(x,y,z):
        print(x)
        print(y)
        print(z)
    
    # test(3,y=5,8)   ##会报错
    # test(3,5,8,y=4) ##也会报错,因为不可以重复赋值给某一形参
    # test(3,8,y=5) ##也会报错,执行时默认将3赋值给x,将8赋值给y test(3,8,z=5) ##正常执行

    4.默认参数

     默认参数:在调用时如果不给它赋值则它等于默认值,默认值可以为任何类型的值

    def handle(x,y=None):
        print(x,type(x))
        print(y)
    
    handle('12ed')       ##不给默认参数赋值的时候,默认参数等于默认值
    handle(2,'hello')

    输出:

    5.参数组

    非固定长度的参数(后期可以扩展):

        *      列表、元组

       **     字典

    • 列表、元组
    def test(x,*args):      ##*代表非固定长度的参数值
        print(x)
        print(args)
        # print(args[1])       ##输出为空元组
    
    test(1,12,4,5,'ds')       ##将第一个实参传给第一个形参,后边所有的实参组合成元组传给第二个形参,该例子中实参可以为任意数据类型
    test(1)                   ##不给第二个形参传值也可以,但需取掉函数中的print(args[1]),否则会报错
    test(1,['1',23,2,2])
    test(1,*['x',12,'q21'])  ##*表示将该列表中的元素遍历,第一种调用函数的方法类似,元组也是如此

    输出:

    • 字典
    def test(x,**kwargs):
        print(x)
        print(kwargs)
    
    test(1,y=2,z=3)    ##将第一个实参后的所有实参组合成一个字典赋值给第二个形参,注意只能使用key=value的形式赋值
    
    #三个混合使用时,只能使用下面的顺序
    # def test1(x,*args,**kwargs):

     五、局部变量与全局变量

        在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。

        全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
        当全局变量与局部变量同名时:
        在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
    name = 'lee'    ##全局变量:顶格写,全局生效
    
    ##局部变量:在子程序中定义的变量,在该子程序之外的部分不生效,例如def自定义函数中
    def  change_name():
        first_name = 'hello'
        # print('my name:',name)    ##全局变量在子程序中也生效,但是当在子函数中如果对该变量重新赋值时,调用该变量的代码块只能出现在其后,否则会报错
        print(first_name)
        name = 'mike'
        print(name)
    
    change_name()   ##调用函数时,如果使用了变量,执行时会默认先在函数内层(即局部变量)找,如果没有再在外部(即全局变量)找
    print(name)     ##局部变量无效,只有全局变量生效

     输出:

    name = 'lee'    ##全局变量:顶格写,全局生效
    
    ##局部变量:在子程序中定义的变量,在该子程序之外的部分不生效,例如def自定义函数中
    def  change_name():
        global name      ##将全局变量引入函数内部,在函数内如果重新定义变量的话就是改变的全局变量,注意如果使用global并且重新对变量赋值,则在函数内global之前不能调用全局变量
        name = 'mike' 
        print(name)
    
    change_name()
    print(name)  ##局部变量无效,只有全局变量生效

    注意:如果函数中没有对变量重新赋值(即指定与全局变量名称相同的局部变量),但局部变量是可变对象(如列表等),可以在函数中直接使用该可变对象的内置方法(如列表的.append方法)

    输出:

     
  • 相关阅读:
    Python学习第七天——随机码生成
    Python学习第六天——Fibonacci
    Python学习第五天——递归函数
    Python学习第四天——文件修改
    Python学习第三天——三级目录
    Python学习第二天——购物车程序
    Python学习第一天——用户名登录退出
    Linux什么时候在pc机上有一席之地
    关于系统设计时性能以及可扩展性的考虑
    HyberLedger Fabric学习(4)-chaincode学习(操作人员)
  • 原文地址:https://www.cnblogs.com/foever-lee/p/10344389.html
Copyright © 2011-2022 走看看