• Python学习记录——函数


    一.函数的作用

    1.减少重复代码

    2.方便修改,易于扩展

    3.保持代码一致性,增强可读性

    二.函数的使用和结构

    1.函数的创建:

    def 函数名(<参数>):

      函数体

    2.函数的调用:函数名(<参数>)

    3.函数的命名规则:和变量一样

    4.函数和变量类似,故函数名也可以进行赋值,如f1=f2,则f2函数与f1函数功能一样

    5.函数的参数:

    (1)形参:

    形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数,类型应与实参一一对应)

    (2)实参:

    实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参   

    (3)区别:

    形参是虚拟的,不占用内存空间,.形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,实参传给形参,不能形参传给实参

    6.实例:

    import time

    times=time.strftime('%Y--%m--%d')  #取出当前时间

    def f(time):

      print('Now  time is : %s'%times)  #利用格式化输出,将变化内容作为参数

    f(times)

    三.函数的参数

    1.必备参数

    (1)备注:必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

    (2)示例:

    def f(name,age):

      print('Name:%s Age:%d' %(name,age))

    f('zhou',20)

    2.关键字参数

    (1)备注:关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

    (2)示例:

    def f(name,age):

      print('Name:%s Age:%d' %(name,age))

    f(age=20,name='zhou')

    3.默认参数

    (1)备注:调用函数时,缺省参数的值如果没有传入,则被认为是默认值。一般放在其他参数的后面。

    (2)示例:

    def f(name,age,sex='male'):

      print('Name:%s   Age:%d   Sex:%s'  %(name,age,sex))

    f('zhou',20)

    f('lin',20,'female')

    4.不定长参数

    (1)备注:一个函数能处理比当初声明时更多的参数,这样的参数叫做不定长参数,和上述2种参数不同,声明时不会命名。

    (2)示例1:(加法器)

    def add(*args):  #*代表参数不定长,且参数为元组形式

      sum=0

      for i in args:

        sum+=i

      print(sum)

    add(1,2,3)

    (3)示例2:(个人信息显示)

    def f(*args,**kwargs):  #**代表参数不定长,且参数为字典形式

      print('Name:%s   Age:%d   Sex:%s'  %(args[0],args[1],args[2]))

      for i in kwargs:

        print(%s:%s %(i,kwargs[i]))

    f('zhou',20,'male',Hobby='invention',Job='student')  #前三个没有键的存入args成为元组,后两个有键的存入kwargs成为字典

    (4)示例3:(将一个列表/字典拆分传输)

    def f(*args/**kwargs):

      print(args/kwargs)

    f(*[1,2,3]/**{'name':'zhou'})  #此时打印结果为1,2,3/{'name':'zhou'}单个元素而不是整个列表/字典

    (5)参数优先级:关键参数>默认参数>*args>**kwargs,必须按照此顺序排列实参

    四.函数的返回值

    (1)要想获取函数的执行结果,就可以用return语句把结果返回

    (2)函数在执行过程中只要遇到return语句,就会停止执行并返回结果,所以也可以理解为 return 语句代表着函数的结束

    (3)如果未在函数中指定return,那这个函数的返回值为None  

    (4)return多个对象,解释器会把这多个对象组装成一个元组作为一个一个整体结果输出。

    (5)函数返回值既可以是一个变量,也可以是一个函数,例如:

    def f():

      def inner():

        return 6

      return inner

    f()  #此时返回的是一个地址,即储存函数代码的地址

    五.函数的作用域

    1.作用域介绍

    (1)L:local,局部作用域,即函数中定义的变量;

    (2)E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;

    (3)G:globa,全局变量,就是模块级别定义的变量;

    (4)B:built-in,系统固定模块里面的变量,比如int, bytearray等。

    (5)搜索变量的优先级顺序依次是:局部作用域>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB(从小到大)

    (6)示例:

    x = int(2.9)  # int built-in

    g_count = 0  # global

    def outer():

      o_count = 1  # enclosing

      def inner():

        i_count = 2  # local

    2.作用域产生

    在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)不会引入新的作用域

    3.变量的修改

    (1)局部作用域只能读取全局作用域的变量,但不能修改:(下面的程序会报错)

    x=1

    def a():

      print(x)#此时拿到的是全局变量10

      x=2  #错误的原因在于print(x)时,解释器会在局部作用域找,会找到x=2(函数已经加载到内存),但x使用在声明前了,所以报错

    a()

    (2)要想修改全局作用域中的变量,需在局部变量前加global

    (3)要想修改嵌套作用域中的变量,需在局部变量前加nonlocal

     六.高阶函数

    1.高阶函数需要满足的条件(至少其中之一):

    (1)接受一个或多个函数作为输入

    (2)输出一个函数

    2.示例:

    def f(n):

      return n*n

    def F(a,b,func)

      print(f(a)+f(b))

    F(1,2,f)  #输出5

    七.递归函数

    1.定义:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

    2.递归函数的优点:定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

    3.递归特性:

    (1)必须有一个明确的结束条件

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

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

    八.内置函数

    1.内置函数大全:https://docs.python.org/3.5/library/functions.html#repr

    2.重要的内置函数:

    (1)filter(function, sequence)  #将sequence中的item一个一个传入function

    示例:

      str = ['a','b','c','d']

      def fun1(s):

        if s != 'a':

          return s

      ret = filter(fun1, str)

      print(list(ret))  #ret是一个迭代器对象

    解释:对sequence中的item依次执行function(item),将执行结果为True的item做成一个filter object的迭代器返回。可以看作是过滤函数。

    (2)map(function, sequence)

    示例1:

      str = ['a','b','c']

      def fun2(s):

        return s+‘zhou’

      ret = map(fun2, str)

      print(list(ret))  #['azhou', 'bzhou', 'czhou']

    解释:对sequence中的item依次执行function(item),将执行结果组成一个map object迭代器返回。

    示例2:

      ef add(x,y):

        return x+y

      print (list(map(add, range(10), range(10))))##[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

    解释:map也支持多个sequence,这就要求function也支持相应数量的参数输入

    (3)reduce(function, sequence, starting_value)

    示例:

      from functools import reduce

      def add1(x,y):

        return x + y  #若为x*y则可以用来做阶乘

      print (reduce(add1, range(1, 101)))  # 5050 (注:1+2+...+99+100)

      print (reduce(add1, range(1, 101), 20))  # 4970 (注:1+2+...+99+20)

    解释:对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用。

    (4)lambda  #匿名函数

    匿名函数的命名规则:

      用lamdba 关键字标识,冒号(:)左侧表示函数接收的参数(a,b) ,冒号(:)右侧表示函数的返回值(a+b)。

    普通函数与匿名函数的对比:

    #普通函数

      def add(a,b):

        return a + b

      print(add(2,3))

    #匿名函数

      add=lambda a,b : a + b, [2,3]

      print(add(2,3))  #一行即可实现上面多行内容,用于代码简化

    #输出

      5

      5

    匿名函数使用范围:当函数名不重要而只用其内容时,可以用lambda将函数体直接引用,省去定义函数的代码

    3.结合使用功能更加强大:

    (1)阶乘:(reduce+lambda)

      from functools import reduce

      print (reduce(lambda x,y: x*y, range(1,6)))

    (2)平方:(map+lambda)

      squares = map(lambda x : x*x ,range(9))

      print (squares)  #<map object at 0x10115f7f0>迭代器

      print (list(squares))  #[0, 1, 4, 9, 16, 25, 36, 49, 64]

  • 相关阅读:
    【JAVA】空指针异常
    【JAVA】分隔字符串的小技巧
    【JAVA】imageio异常:不支持图像类型
    权限设计“终极”解决方案
    一直困扰我的.net 2.0和,net 1.1同时运行的问题解决了
    乱谈成本三
    SandBar学习笔记
    不是吧!怎么这样
    学习Java的相关知识
    代码自动生成工具的补充
  • 原文地址:https://www.cnblogs.com/zhoujianlin/p/8511973.html
Copyright © 2020-2023  润新知