Python基础(三)

作者: EvanForEver | 来源:发表于2018-02-08 19:44 被阅读16次

    Python中的函数

    1. 函数的意义:
    • 对输入进行变换映射后输出
    • 过程化VS 结构化
    1. 函数的创建及结构:
    • 定义函数名
    • 参数
    • 函数体
    • 返回
       有无返回
      (无返回值即无return或者return后为空。return返回的是对象,如返回对象数>1则返回元组)
       return与yield的区别
      (return:函数执行到return处返回一个对象,函数结束)
      (yield:函数执行到yeild处返回一个生成器,记录函数执行情况,再次调用会接着执行)

    函数中的参数

    1. 参数语法:func(positional_args,keyword_args,*tuple_nonkw_args,**dict_kw_args)
    2. 按参数传递方式:
       位置参数(别称:定位参数,非关键字参数) :对位置敏感,传递时不用指定参数名
       关键字参数:不传关键字参数函数可以被调用,采用默认值,传关键字参数,覆盖默认值
       位置参数包裹及使用* (非关键字不定长参数 args*)
       关键字参数包裹及使用**(关键字的不定长参数 kwargs*)
       包裹解包顺序(首先拆位置参数包裹,按顺序给必选,默认,可变、关键字参数包裹)
       传递参数时使用包裹
    #位置参数包裹及使用*,一次传入不定长个位置参数
    >>def mysum2(*args):
    >>    print(type(args))
    >>    return sum(args)
    >>mysum2(5,7,5,8,9)#正常调用
    <class 'tuple'>
    34
    
    >>def filmInfo(**kwargs):
    >>    print(type(kwargs))
    >>    for key,values in kwargs.items():
    >>        print(key,':',values)
    
    #关键字参数包裹及使用**,一次性传入不定长关键字参数
    >>filmInfo(film='羞羞的铁拳',box=3.5,rate=7.9)
    <class 'dict'>
    film : 羞羞的铁拳
    box : 3.5
    rate : 7.9
    
    #传递参数时使用包裹
    #传递参数时使用包裹-位置参数
    >>l1=[1,5,6,7,2,5,3.5,9,6,3,4]
    >>mysum2(*l1)
    <class 'tuple'>
    51.5
    
    #zip案例
    >>l1=[(1,3),(2,4),(5,6)]
    >>list(zip(*l1)) #即 list(zip(l1[0],l1[1],l1[2]))
    [(1, 2, 5), (3, 4, 6)]
    
    ##传递参数时使用包裹-关键字型参数
    >>d1={'羞羞的铁拳':3.5,'雷神3':3.1,'战狼2':60}
    >>filmInfo(**d1)
    <class 'dict'>
    羞羞的铁拳 : 3.5
    雷神3 : 3.1
    战狼2 : 60
    
    
    1. 按参数的类型:
       必选(位置参数)
       关键字/默认
       *args可变长位置参数,**kwargs可变长关键字参数
    2. 函数如何处理传入参数:
       值传递参数与指针传递参数
      (值传递时(数值和字符串),变量传递给函数后,函数复制一份,不会影响原有变量)
      (指针(或引用)传递时(列表和字典),传递给函数的是引用,该引用可以改变原变量)

    变量作用域

    locals()#查看局部变量名称空间
    globals()#查看全局变量名称空间

    1. 全局变量
       在模块内、在所有函数外面、在class外面
       供全局共享,全局类和函数均可访问,达到同步作用。使用时,需要用global显示声明
       程序执行时除非被del才会消失
    2. 局部变量
       函数内部创建与访问
       只在函数调用时存在,调用结束后变量不存在
       搜索时:局部作用域->全局作用域

    偏函数PFA

    • 偏函数Partial function application:如果一个函数的参数很多,而在每次调用的时候有一些又经常不需要被指定时,就可以使用偏函数(近似理解为默认值)
       语法:partical(func,*args,**keywords)
       使用:from functools import partial
       原理:创建一个新函数,固定住原函数的部分参数(可以为位置参数,或是关键字参数)
    >>def hex2int1(x,base=16):
    >>    #base为关键字参数,在调用int函数时固定给16。用来转换16进制到10进制
    >>    return  int(x,base)
    >>hex2int('F')
    #相当于:int('F',base=16),这样就少写了一个参数
    
    #functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义
    >>import functools
    >>max100=functools.partial(max,100)
    #定义一个叫max100的偏函数,将这个偏函数的第一个值固定为100
    >>max100(101)#这时调用它,传入的值与100进行比较并返回较大的值。
    101
    

    递归函数

    定义:函数在内部调用自身

    #使用递归分解质因数
    >>l1=[]
    >>def fenji(num):
    >>    num=int(num)
    >>    for i in range(2,num):
    >>            if num%i==0:
    >>                l1.append(i)
    >>                nextv=int(num/i)
    >>                fenji(nextv)
    >>                break#这里的break不加就会硬循环60次                
    >>    return l1
    >>fenji(60)
    [2, 2, 3]
    
    #阶乘
    >>def factorial(n):
    >>    if n==1:
    >>        return 1
    >>    else:
     >>       return n*factorial(n-1)
    >>factorial (5)
    120
    

    高阶函数

    • 函数的引用与调用
       引用:同一个对象被多个不同的变量名引用,函数对象的引用可以del删除
       调用:函数名加(),使用函数
       函数对象既然可以被引用,那就可以作为参数被传入或作为结果被返回
    • 高阶函数: 一个函数接收另一个函数作为参数
    • 回调函数: 函数作为调用函数的结果返回
    #高阶函数
    >>def mycalucate(num,func):
    >>    return func(num)
    
    >>l1=[5,8,3,6,9,15,22]
    
    >>mycalucate(l1,max)
    >>mycalucate(l1,min)
    
    
    #回调函数
    def callbackfunc(*num):
        return max
    callbackfunc(53,5,33)
    

    BIFs中的高阶函数

    1. filter
       语法:filter(function,list)
       使用:function函数对列表的每个元素进行判断,返回True或 False;filter()则根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
      list(filter(lambda x:True if type(x)==str else False,l1))
    2. map
       语法:map(function, list)
       使用:list的每一个元素依次调用function函数,并获取返回值存入一个新的list中。
      map(lambda x:(x,l1.count(x)),l1)
    3. reduce
       语法:reduce(function, list)
       使用:函数function必须包含两个参数,reduce()对list的每个元素反复调用函数function,并返回最终结果值。
      from functools import reduce ; reduce(lambda a,b:a+b,[1,2,3,4,5,6,7,8])
       Python 3.x中,reduce()函数和partical一样被放置在fucntools模块中。使用前需要调用

    匿名函数lambda

    • 语法:lambda(args1,args2, argsN):expression
    • 使用:
       定义后,赋值给一个变量,做正常函数使用
       lambda关键字定义在高阶函数的参数位上
    #使用1:作为正常函数使用,不推荐
    >>foo=lambda x,y:x+y #不用写return
    >>print(foo(5,6))
    11
    
    #使用2:lambda关键字定义在高阶函数的参数位上
    >>d1={'china':15,'India':9,'USA':2,'Japan':1.5}
    # 这里sorted是高阶函数,key接受一个函数,选择排序的参照物
    >>sorted(d1.items(),key=lambda x:(x[0],x[1]))
    #按d1.items()第0个元素升序,国家名相同按人口数排列 
    # sorted(d1.items(),key=lambda x:(x[1]))#按第1个元素人口数升序排列
    
    

    闭包Closure

    • 定义:涉及嵌套函数时才有闭包问题,内层函数引用了外层函数的变量(参数),然后返回内层函数的情况,称为闭包(Closure)。
       这些外层空间中被引用的变量叫做这个函数的环境变量。
       环境变量和这个非全局函数一起构成了闭包。
    • 闭包的特点:函数会记住外层函数的变量
    >>nums_in_global=[15,2,3,9,3.2]#声明一个全局
    
    >>def foo1(nums_in_function):
    >>    print('nums_in_function此时在是foo1中,可以被访问:',nums_in_function)
    >>    def foo2():
    >>        return max(nums_in_function)
               #虽然没有给foo2传入任何参数,但foo2却能访问到foo1中的变量>>nums_in_function
    #         return max(nums_in_global)
               #虽然没有给foo2传入任何参数,但foo2却能访问到全局变量nums_in_global
           return foo2
    #调用
    >>foo1([5,3,8])()
    nums_in_function此时在是foo1中,可以被访问: [5, 3, 8]
    8
    >>foo1([5,3,8])
    nums_in_function此时在是foo1中,可以被 访问: [5, 3, 8]
    <function __main__.foo1.<locals>.foo2>
    

    装饰器Decorator

     定义:以函数作参数并返回一个替换函数的可执行函数,为已存在的对象添加额外功能,本质上就一个返回函数的高阶函数
     应用:给函数动态增加功能(函数)
     使用:@是python装饰器的简便写法,也叫语法糖,语法糖在要被包裹的函数前声明。

    #现有如下 三个函数
    def foo1():
        print ('this is foo1 function')
    
    def foo2():
        print ('this is foo2 function')
    
    def foo3():
        print ('this is foo3 function')
        
    #现在想为每一个函数都添加一个打印当前时间的功能
    #方法一:在每个函数中各添加代码打印时间,过于麻烦
    #方法二:写一个函数,负责打印时间,然后在原来的三个函数中调用
    #方法三:先写一个函数接收并打印时间,再调用原函数。
    def foo1():
        print ('this is foo1 function')
    
    def foo2():
        print ('this is foo2 function')
    
    def foo3():
        print ('this is foo3 function')
    
    def extrafoo(func):
        print(datetime.datetime.now())
        return func
    
    decorated=extrafoo(foo2)
    decorated()
    #方法四:使用装饰器
    import datetime
    def extrafoo(func):
        def inner():
            print('extra:',datetime.datetime.now())
            print('from inner to execute:',func.__name__)
            print('the',func.__name__,'result:',func())
        return inner
    
    @extrafoo#装饰器特性,被装饰的函数定义之后立即运行。
    >>def foo1():
    >>    return 'this is foo1 function--'
    
    >>foo1()
    extra: 2018-02-08 19:38:26.047277
    from inner to execute: foo1
    the foo1 result: this is foo1 function--
    
    

    相关文章

      网友评论

        本文标题:Python基础(三)

        本文链接:https://www.haomeiwen.com/subject/igrazxtx.html