• 第五篇 函数进阶


    第五篇 函数进阶

    ==回顾基础==

    函数对象:可以将定义在函数内的函数返回到全局使用,从而打破函数的层级限制.

    名称空间与作用域:作用域关系在函数定义阶段时就已经固定死了,与调用位置无关,即在任意位置调用函数都需要跑到定义函数时找到作用域关系.

    一 闭包函数

    闭包

    闭就是封闭(函数内部函数),包就是包含(该内部函数对外部作用域而非全局作用域的变量的引用).闭包指的是:函数内部函数对外部作用域而非全局作用域的引用.

    提示

    之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,包起来咯,包起哟,包起来哇

    def outter():
        x = 1
        def inner():
            print(x)
         return inner
    
    f = outter()
    
    def f2():
        x = 2
        f()
        
    f2()
    
    # 1
    两种为函数传参的方式
    1. 使用参数的形式
    2. 包给函数
    闭包函数的应用

    闭包的意义:返回的函数对象,不仅仅是一个函数对象,在函数还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域.

    应用领域:延迟计算(原来我们是传参,现在我们是包起来),爬虫领域.

    import requests
    
    def ger(ur1):
        response = requests.get(ur1)
        print(f"done: {ur1}")
        
    get('https://www.baidu.com')
    get('https://www.baidu.com')
    get('https://www.baidu.com')
    
    get('https://www.cnblogs.com/linhaifeng')
    get('https://www.cnblogs.com/linhaifeng')
    get('https://www.cnblogs.com/linhaifeng')
    

    二 装饰器

    无参装饰器

    什么是装饰器

    装饰器指的是为被装饰器对象添加额外功能.因此定义装饰器就是定义一个函数,只不过该函数的功能是用来为其他函数添加额外功能的.

    需要注意的是:

    1. 装饰器本身其实是可以任意调用的对象
    2. 被装饰器的对象也是可以是任意可调用的对象
    装饰器作用

    对已上线的软件进行维护,添加新的功能,但不改变其原来的用法,必须遵循一下原则;

    1. 不修改被装饰对象的源代码
    2. 不修改被装修对象的调用方式
    用法
    1. 改变调用方式""

      import time
      
      def index():
          print('welcome to index')
          time.sleep(1)
      
      def time_count(func):
          start = time.time()
          func()
          end = time.time()
          print(f'{func} time is {start-end}")
      
      time_count(index)
    2. 包给函数-外包

      import time
      def index():
          print('welcome to index')
          time.sleep(1)
      
      def time_count(func):
          #func = 最原始的index
          def wrapper():
              start = time.time()
              func()
              end = time.time()
              print(f"{func} time is {start-end}")
           return wrapper
      # f= time_count(index)
      # f()
      
      index = time_conut(index)
      wrapper
      index()   #wrapper()

    ==完善装饰器==

    上述的装饰器,最后调用index()的时候,其实是在调用wrapper(),因此如果原始的index有返回值的时候,wrapper()函数的返回值应该和index()的返回值相同,也就是说,我们需要同步原始的index()和wrapper()方法的返回值.

    装饰器模板
       def deco(func):
       
            def wrapper(*args,**kwargs):
       
                        res = func(*args, **kwargs)
       
                        return res
       
            return wrapper

    有参装饰器

    无参装饰器只套了两层,有参装饰器可以套三层.

    由于两层装饰器,参数必须得固定位func,但是三层的装饰器解除了这个限制.我们不仅仅可以使用上述单个参数的三层装饰器,多个参数的只需要在三层装饰器中多加入几个参数即可,也就是说装饰器三层即可,多加一层反倒无用.

    详解[]https://www.cnblogs.com/nickchen121/p/10771174.html

    三 迭代器

    可迭代对象

    python中一切皆对象,对于这一切对象中,但凡有——iter——方法的对象,都是可迭代对象

    python内置可迭代对象:str,list,tuple,dict,set,file

    迭代器对象

    只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法让其他的可迭代对象不依赖索引取值。

    在找到该方法前,首先我们给出迭代器对象的概念:可迭代的对象执行——iter——方法得到的返回值。并且可迭代对象会有一个——iter——方法得到的返回值。并且可迭代对象会有一个——next——方法。

    我们可以使用while循环。其中使用的try...except...为异常处理模块

    ==总结==、

    迭代器对象:执行可迭代对象的——iter——方法,拿到返回值就是迭代器对象。

    特点:

    1. 内置——next——方法,执行该方法会拿到迭代器对象中的一个值
    2. 内置有——iter——方法,执行该方法会拿到迭代器本身
    3. 文件本身就是迭代器对象

    缺点:

    1. 取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
    2. 无法使用len()方法获取长度
    for循环原理

    for循环称为迭代器循环,in后必须是可迭代的对象。

    因为迭代器使用——iter——后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。

    由于对可迭代对象使用——iter——方法后变成一个迭代器对象,这个迭代器对象只是占用了一小块内存空间,他只有使用——next——后才会吐出一个一个值。

    四 三元表达式

    条件成立时的返回值if条件else条件不成立时的返回值

    五 列表推导式

    [expression for item1 in iterable1 if condition1
    for item2 in iterable2 if condition2
    ...
    for itemN in iterableN if conditionN
    ]
    类似于
    res=[]
    for item1 in iterable1:
        if condition1:
            for item2 in iterable2:
                if condition2
                    ...
                    for itemN in iterableN:
                        if conditionN:
                            res.append(expression)

    六 字典生成式

    通过解压缩函数生成一个字典

    info_dict = {'name': 'nick', 'age': 19, 'gender': 'male'}
    print(f"info_dict.keys(): {info_dict.keys()}")
    print(f"info_dict.values(): {info_dict.values()}")
    
    res = zip(info_dict.keys(), info_dict.values())
    print(F"zip(keys,values): {zip(info_dict.keys(),info_dict.values())}")
    
    info_dict = {k: v for k, v in res}
    print(f"info_dict: {info_dict}")

    七 生成器

    生成器本质就是迭代器,同时又不仅仅是迭代器,不过迭代器之外的用途不是很多;生成器提供了非常方便的自定义迭代器的途径。

    yield关键字

    yield的英语单词意思时生产,在函数中但凡出现yield关键字,再调用函数,就不会执行函数体代码,而是会返回一个值。

    生成器表达式

    把列表推导式的[]换成()就是生成器表达式

    优点:省内存,一次只产生一个值在内存中

    总结

    yield:

    1. 提供一种自定义迭代器的方式
    2. yield可以暂停住函数,并提供当前的返回值

    yield和return:

    1. 相同点:两者都是在函数内部使用,都可以返回值,并且返回值没有类型和个数的限制。
    2. 不同点:return只能返回一次值,yield可以返回多次值

    八 递归

    函数的嵌套调用是:函数嵌套函数。函数的递归调用:它是一种特殊的嵌套调用,但是它在调用一个函数的过程中,又直接或间直接调用了它自身。如果递归函数不断地带调用函数自身,那么这个递归函数将进入死循环,因此我们应该给递归函数一个明确的结束条件。

    1. 直接调用:指的是直接在函数内部调用函数自身。
    2. 间接调用:间接调用指的是:不在原函数体内调用函数自身,而是通过其他方法间接调用函数自身。

    递归必须要有两个明确的阶段:

    1. 递推:一层一层递归调用下去,进入下一层递归的问题规模将会减小。

    2. 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯

      递归的精髓在于通过不断地重复逼近一个最终的结果。

    九 匿名函数

    有名函数

    我们之前定的函数都是有名函数,它是基于函数名使用。

    匿名函数

    匿名函数,他没有绑定名字,使用一次即被收回,加括号既可以运行。

    与内置函数联用

    匿名函数通常与max(),sorted(),filter(),filter()方法连用。

    取最大值,可以用max,max默认比较的是字典的key:

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当作参数传给key指定的函数,然后将该函数的返回值当作判断依据。

    对字典值排序,使用sorted方法:

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当作参数传给第一个参数指定的函数,然后该函数的返回值当作判断依据。

    对列表中的某一数据做处理,可以用map方法

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当作参数传给第一个参数传给指定的函数,然后该函数的返回值作为map方法的结果之一.

    帅选含有你想要的数据,可以用filter方法:

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当作参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下.

    十 内置函数

    掌握
    1. bytes

      解码字符

    2. chr/ord

      照ASCIL码表将数字转换成对应字符,ord()将字符转换成对应数字

    3. divmod

      分栏

    4. enumrate

      带有索引的迭代

    5. eval

      把字符串翻译成数据类型

    6. hash

      是否可以哈希

    了解
    1. abs

      求绝对值

    2. all

      可迭代对象内元素为真,则返回真

    3. any

      而迭代对象中有一元素为真,则为真

    4. bin/oct/hex

      二进制,八进制,十六进制转换

    5. dir

      列举出所有time的功能

    6. frozenset

      不可变集合

    7. goabals/locals

      查看全局名字;查看局部名字

    我把月亮戳到天上 天就是我的 我把脚踩入地里 地就是我的 我亲吻你 你就是我的
  • 相关阅读:
    input填入字符会出现黄色
    安装Scrapy时出现问题scrapy unicodedecodeerror ascii codec cant decode byte 0xd1 in position
    SVN 出现:Previous operation has not finished; run 'cleanup' if it was interrupted。
    Myeclipse小技巧
    好的开发网站
    BZOJ 1968
    BZOJ 1010
    BZOJ 1015
    BZOJ 3875
    BZOJ 2705
  • 原文地址:https://www.cnblogs.com/zhulipeng-1998/p/12863932.html
Copyright © 2020-2023  润新知