• 11-Python-函数


    1、函数的定义

    定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。其特性如下:

    • 减少重复代码
    • 使程序变的可扩展
    • 使程序变得易维护

    2、语法定义

    1 def func1():
    2     '''test1'''  #声明函数的作用
    3     print("test function1")
    4     return 0  #返回值
    5 
    6 func1()  #调用函数
    7 x = func1()  #将函数返回值赋值给x
    8 print(x)

    3、函数返回值

    返回值个数=0,返回None
    返回值个数=1,返回object
    返回值个数>1,返回tuple

    4、带有参数的函数

    4.1、普通参数

    函数的参数又分为形式参数实际参数

    • 形参变量:只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
    • 实际参数:可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。
    1 def func1(x,y):
    2     print(x)
    3     print(y)
    4 
    5 func1(1,2)  #位置参数,实参与形参一一对应,与位置有关
    6 func1(y=2,x=1)  #关键字参数,与位置无关。但是需要注意的是:关键字参数必须在位置参数之后。
    7 
    8 func1(10,y=20) 
    9 # func1(x=10,20)  这样写不行,因为关键字参数不能写在位置参数前面

     

    4.2、默认参数

    默认参数必须放在形参和*args的后面,**kwargs的前面。

     1 #现有代码如下:
     2 def stu_register(name,age,country,course):
     3     print("----注册学生信息------")
     4     print("姓名:",name)
     5     print("age:",age)
     6     print("国籍:",country)
     7     print("课程:",course)
     8  
     9 stu_register("王山炮",22,"CN","python_devops")
    10 stu_register("张叫春",21,"CN","linux")
    11 stu_register("刘老根",25,"CN","linux")
    12 
    13 #发现country都是相同的,因此可以给该参数一个默认值:
    14 def stu_register(name,age,course,country='CN'):  #默认参数必须放形参的后面
    15     print("----注册学生信息------")
    16     print("姓名:",name)
    17     print("age:",age)
    18     print("国籍:",country)
    19     print("课程:",course)
    20  
    21 stu_register("王山炮",22,"python_devops")
    22 stu_register("张叫春",21,"linux")
    23 stu_register("刘老根",25,"linux")

    4.3、非固定参数

    若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数。非固定参数必须放置形式参数之后,且*args放置在默认参数之前,**kwargs放置在*args和默认参数之后。 

     1 #*args:接收N个位置参数,转换成元组
     2 def stu_register(name,age,*args): # *args 会把多传入的参数变成一个元组形式,且*args必须放在形参之后,默认参数之前
     3     print(name,age,args)
     4    
     5 stu_register("Alex",22)  #Alex 22 () #输出:Alex 22 () #后面这个()就是args,只是因为没传值,所以为空元组
     6 
     7 stu_register("Jack",32,"CN","Python")  #输出:Jack 32 ('CN', 'Python')
     8 
     9 #注意默认参数的位置,只能放在*args之后
    10 def stu_register(name,age,*args,sex="Male"): # *args 会把多传入的参数变成一个元组形式,且*args必须放在形参之后,默认参数之前
    11     print(name,age,args,sex) 
    12 
    13 stu_register("Jack",32,"Python","CN")  --> Jack 32 ('Python','CN') Male
    14 
    15 #如果默认参数放在*args之前,那么会出现如下的情况:
    16 def stu_register(name,age,sex="Male",*args):
    17     print(name,age,sex,args)
    18     
    19 stu_register("Jack",32,"Python","CN")    -->  Jack 32 Python ('CN',)  # 位置参数Python传递的值会覆盖形式参数sex的默认值Male
    20 # stu_register("Jack",32,sex="Male","Python","CN")这样又会报错,因为关键字参数不能出现在位置参数之前。
    21 
    22 #*args传递参数的方式
    23 def func3(*args):
    24     print(args)
    25 
    26 func3(1,2,3,4,5)
    27 #如果传递列表或元组,想达到和如上一致的效果,那么就在列表或元组前加*
    28 func3(*[1,2,3,4,5]) --> (1,2,3,4,5) # 站在实参的角度上,给序列(列表、元组)加上*,就是将这个序列按照顺序打散,传递给形参。站在形参的角度上,给变量加上*,就是按顺序组合所有传递过来的值。
    29 func3(*(1,2,3,4,5)) --> (1,2,3,4,5)
    30 #而如果直接传递列表或者元组,那么结果也是列表或元组
    31 func3([1,2,3,4,5], )  -->  ([1, 2, 3, 4, 5],)
    32 func3((1,2,3,4,5), )  -->  ((1, 2, 3, 4, 5),)
    33 
    34 
    35 #**kwargs:接收N个关键字参数,转换成字典
    36 
    37 #**kwargs传递参数的方式
    38 def func4(**kwargs):
    39     print(kwargs)
    40     
    41 func4(a=1,b=2)  #和如下的传参方式等价
    42 
    43 d1 = {"a"=1, "b"=2}
    44 func4(**d1)  # 如果想以字典的方式传递值,那么就要在字典前加上**。道理和*args传参方式一致
    45 
    46 #传递多种类型的参数
    47 def stu_register(name,age,*args,sex="male",**kwargs): # **kwargs 会把多传入的参数变成一个字典形式,且**kwargs必须放在形参、*args和默认参数之后
    48     print(name,age,args,sex,kwargs)
    49   
    50 stu_register("Alex",22)  #输出:Alex 22 () male {} #()是args,因为没传值,所以是空元组;后面这个{}就是kwargs,因为没传值,所以为空字典
    51 
    52 stu_register("Druid",32,"python",hobby="Female",province="ShanDong") #输出:Druid 32 ('python',) male {'hobby': 'Female', 'province': 'ShanDong'}

     

    4.4、lambda表达式

     1 #普通函数
     2 def func1(x):
     3     return  x+100
     4 
     5 res = func1(100)
     6 
     7 #lambda表达式,等价于上面的函数
     8 func1 = lambda x:x+100
     9 
    10 res = func1(111)
    11 print(res)
    12 
    13 #lambda表达式之多参数
    14 func2= lambda x,y:x+y+100
    15 
    16 res1 = func2(11,22)
    17 print(res1)
    18 
    19 #lambda表达式之默认参数
    20 func3 = lambda x,y=22:x+y+1001
    21 res2 = func3(11)
    22 print(res2)

    4.5、递归

    如果一个函数在内部调用自身本身,这个函数就是递归函数。

    递归特性:

    1. 必须有一个明确的结束条件。

    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少。

    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)。

    堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.htm

    1 def calc(num):
    2     print(num)
    3     if num//2 >= 1:  #结束的条件
    4         return calc(num//2)
    5 
    6 calc(10)  #输出:10 5 2 1

    5、高阶函数

    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

    1 def add(a,b,f):
    2     return f(a)+f(b)
    3 
    4 res = add(-10,10,abs)  #将abs函数作为参数传递,然后在目标函数的内部用该函数进行计算
    5 print(res)

    6、闭包

       如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

      

      当循环结束以后,循环体中的临时变量不会销毁,而是继续存在于执行环境中。且python的函数只有在执行时,才会去找函数体里的变量的值。

    funclist = []  
    for i in range(3):  
        def foo(x): print x + i  
        flist.append(foo)  
    for f in funclist:  
        f(2)
    
    #  --->输出结果为4 4 4。
  • 相关阅读:
    Visual Studio LightSwitch
    Android 虚拟机与真机调试配置
    点击手机 menu 硬件按钮后的显示及处理
    Windows Phone 7 真机调试
    Android 调试
    Android 新建项目 页面
    今天我的Windows Phone 7 HTC HD7 手机 升级 NoDo 了 分享一下经验
    Activity 之间调用与参数传递
    Android widget 组件
    解决 warning: found plain 'id' attribute; did you mean the new 'android:id' name? 问题
  • 原文地址:https://www.cnblogs.com/Druidchen/p/7755677.html
Copyright © 2020-2023  润新知