函数

作者: Snackk | 来源:发表于2018-08-25 16:26 被阅读0次

    函数:

    内置函数(链接)
    一.函数初始
    默认参数的陷阱
    默认参数若是可变的数据类型,他始终使用的是一个内存地址。

    def func1(x,l1=[]):
        l1.append(x)
        return l1
    ret = func1(1)
    ret1 = func1(100)
    

    return是函数结束的标志,函数内可以写多个return,但只执行一次
    无return 返回None
    只写return,后面不写其他内容,也会返回None
    return 逗号分隔多个值 返回元组
    返回多个值,用多个变量接收
    a,b,c,d = ret_demo2()

    形参即变量名,实参即变量值
    函数即变量 函数的赋值 f = func
    命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
    可以保证,传入的参数中一定包含某些关键字

    def foo(位置形参,*args,默认参数,**kwargs):
        函数体
        return 返回值
    
    

    动态参数
    溢出的位置参数值以元祖形式赋给args ,溢出的关键字参数以字典的形式赋给kwargs

    *args,**kwargs
    函数定义时:*聚合  *args:实参里面所有的位置参数。
                       **kwargs:实参里面所有的关键字参数。
    函数的调用时:* 打散。
    形参的顺序:位置参数,*args,默认参数,**kwargs。
    

    二.函数进阶

    存放名字与值的关系’的空间起了一个名字-------命名空间。

    全局名称空间。
    临时名称空间。
    内置名称空间。
    全局作用域: 全局名称空间,内置名称空间。
    局部作用域: 局部名称空间。
    取值顺序:就近原则,从小到大。
    加载顺序:加载的是名称空间。
    global nonlocal
    globals() locals() 以字典形式返回模块全部全局变量和局部变量

    全局作用域:包含内置名称空间、全局名称空间
    局部作用域:局部名称空间,只能在局部范围内生效
    
    • 函数名的本质。

    函数名本质上就是函数的内存地址。

    • 1.可以被引用

    • 2.可以被当作容器类型的元素

    • 3.可以当作函数的参数和返回值

    第一类对象(first-class object)指
    1.可在运行期创建
    2.可用作函数参数或返回值
    3.可存入变量的实体。

    • 一句话,函数名能当普通变量用

    嵌套函数:
    匿名函数:使用一次就释放

    • lambda x,y:x**y
    • 匿名函数主要是和其它函数搭配使用

    高阶函数:
    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
    只需满足以下任意一个条件,即是高阶函数

    • 接受一个或多个函数作为输入
    • return 返回另外一个函数
    def add(x,y,f):
        return f(x) + f(y)
    

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

    查看递归次数

    n = 1
    def func(x):
        print(x)
        x+=1
        func(x)
    func(n)
    
    def calc(n):
        v = int(n/2)
        print(v)
        if v > 0:
            calc(v)
        print(n)
    
    calc(10)
    

    递归特性:

    • 必须有一个明确的结束条件
    • 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
    • 递归效率不高,递归层次过多会导致栈溢出()
      应用:二分查找

    闭包原理
    闭包函数:内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数,并返回.
    闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
    应用领域:延迟计算(原来我们是传参,现在我们是包起来)
    闭包作用:
    当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
    如果这个函数内部形成了闭包,
    那么他就不会随着函数的结束而消失。

    name = 'alex'
    def wraaper():
        def inner():
            print(name)
        print(inner.__closure__)  # None不是闭包函数
        inner()
        return inner
    wraaper()
    
    
    name = 'hqs'
    def wraaper(n):
        n = 'alex'
        def inner():
            print(n)
        print(inner.__closure__)  # cell at 0x000002AD93BF76D8 --> 是闭包函数
        inner()
        return inner
    wraaper(name)
    

    可迭代对象:Iterable
    : str list dict,tuple,set,range()

    对象内部含有iter方法就是可迭代对象.

    print('__iter__' in dir(对象))  #返回True.False
    
    from collections import Iterable #判断是否是可迭代对象
    from collections import Iterator #判断是否是迭代器
    print(isinstance('对象',Iterable))  # True/False
    print(isinstance('对象',Iterator))  # True/False
    

    可迭代对象满足可迭代协议。

    迭代器:Iterator
    对象内部含有__iter__方法且含有__next__方法就是迭代器.
    文件本身就是迭代器对象

    迭代器的缺点:

    • 取值麻烦,只能一个一个取,只能往后取,
    • 并且是一次性的,无法用len获取长度

    可迭代对象不能取值,迭代器是可以取值的。
    可迭代对象 --->(转化成)迭代器
    迭代器=可迭代对象.iter() #等于 迭代器=iter(可迭代对象) #转化

    1,将可迭代对象转化成迭代器。
    2,调用next方法取值。
    3,利用异常处理停止报错。

    模式for循环

    迭代器 = 可迭代对象.__iter__()
    while 1:
        try:
            print(迭代器.__next__())
        except StopIteration:
            break
    

    装饰器:

    开放封闭原则:
    软件上线后,对修改源代码是封闭的,对功能的扩展功能是开放的。
    方案:装饰器

    原则:
        * 1,不修改原代码
        * 2,不修改调用方式
    目的:
        遵循1和2的基础上拓展新功能
    

    装饰器:
    装饰为被装饰对象添加新功能
    含义:
    装饰器即在不修改被装饰对象源代码与调用方式的前提下,为被装饰对象添加新功能

        装饰器 ==》函数
        被装饰的对象 ==》函数
    
        time.time() 获取当前时间(s)
    

    生成器:就是自己python用代码写的迭代器,生成器的本质就是迭代器。
    generator是可迭代对象 , 可用for循环和next()

    用以下两种方式构建一个生成器:

    • 1,通过生成器函数。
    • 2,生成器表达式。

    生成器函数 vs 迭代器:

    • 迭代器是需要可迭代对象进行转化。可迭代对象非常占内存。
    • 生成器直接创建,不需要转化,从本质就节省内存。
    • send 与next一样,也是对生成器取值(执行一个yield)的方法。
    • send 可以给上一个yield 传值。
    • 第一次取值永远都是next。
    • 最后一个yield 永远也得不到send传的值。
    • yield 将值返回给 生成器对象.next()

    迭代器.next() 相当于 next(迭代器)

    把函数做成迭代器
    * 对比return,可以返回多次值,挂起函数的运行状态
    创建生成器:如下

    def func1():  #生成器函数
        print(1)
        count = (yield 6)
        print(count)
        count1 = (yield 7)
        print(count1)
        yield 8
    
    g = func1()  #调用生成器函数创建生成器对象
    
    print(next(g))
    print(g.send('alex'))
    print(g.send('alex'))
    
    def cloth2(n):
        for i in range(1,n+1):
            yield '衣服%s号' % i
    g = cloth2(10000)
    for i in range(50):
        print(g.__next__())  #停在50的位置
    
    for i in range(50):      #从51开始
        print(g.__next__())
    

    列表推导式

    • 循环模式 : [变量(加工后的变量) for 变量 in iterable]
    • 筛选模式 : [变量(加工后的变量) for 变量 in iterable if 条件]
      优点:一行解决,方便。
      缺点:容易着迷,不易排错,不能超过三次循环。
      列表推导式不能解决所有列表的问题,所以不要太刻意用。

    生成器表达式:
    将列表推导式的 [] 换成() 即可。

    三元表达式:ret = 'true' if 1 == 1 else 'false'

    相关文章

      网友评论

          本文标题:函数

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