zoukankan      html  css  js  c++  java
  • python函数进阶知识整理

    函数进阶知识整理

    闭包函数

    把函数inner和变量x包在函数outter内部,然后通过函数outter的返回值返回出函数inner对象

    def outter(x):
        x = 1
    
        def inner():
            print(x)
        return inner
    
    
    f = outter(1)
    f() #1
    # 查看闭包的元素
    print(F"f.__closure__[0].cell_contents{f.__closure__[0].cell_contents}") 
    # f.__closure__[0].cell_contents: 1
    

    装饰器

    用来给函数加功能的,他的本质也是函数

    为什么用装饰器

    假设我们已经上线了一个项目,我们需要修改某一个方法,但是我们不想修改方法的使用方法,这个时候可以使用装饰器。因为软件的维护应该遵循开放封闭原则,即软件一旦上线运行后,软件的维护对修改源代码是封闭的,对扩展功能是开放的。

    注意:

    1. 不能改变被装饰函数的源代码

    2. 不能改变被装饰函数的调用方式

      装饰器模板

    def outter(func):
        def wrapper(*args,**kwrags):
            # 逻辑
            res = func(*args,**kwargs)  # func是被装饰的函数
            return res
        return wrapper
    
    @outter   #装饰器语法糖 (更精简的代码)  
    # index = outter(index)  # index = wrapper
    # index()
    def index():
        pass   
        
    # 三层装饰器模板  给双层装饰器加参数
    def sanceng(engine):
        def outter(func):
            def wrapper(*args,**kwrags):
                # 逻辑
                res = func(*args,**kwargs)  # func是被装饰的函数
                return res
            return wrapper
       	return outter
       	
    @sanceng(engine)
    def index():
        pass
    

    迭代器

    迭代器即迭代的工具,那什么是迭代呢?`
    迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值

    为何要有迭代器

    对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

    #优点:
      - 提供一种统一的、不依赖于索引的迭代方式
      - 惰性计算,节省内存
    #缺点:
      - 无法获取长度(只有在next完毕才知道到底有几个值)
      - 一次性的,只能往后走,不能往前退
    

    for循环称为迭代器循环

    # 含有__iter__方法的对象叫做可迭代对象,除了数字类型和函数之外都是可迭代对象,可迭代对象不一定是迭代器对象
    s = 'nick'
    s_iter = s.__iter__()
    
    
    # 含有__iter__和__next__方法的对象叫做迭代器对象,只有文件是迭代器对象,迭代器对象一定是可迭代对象
    s = 'nick'  # 可迭代对象,不属于迭代器对象
    s.__iter__()
    lt = [1, 2, 3]  # 可迭代对象,不属于迭代器对象
    dic = {'a': 1, 'b': 2}  # 可迭代对象,不属于迭代器对象
    tup = (1,)  # 元组只有一个元素必须得加逗号# 可迭代对象,不属于迭代器对象
    se = {1, 2, 3}  # 可迭代对象,不属于迭代器对象
    f = open('time.py')  # 可迭代对象,迭代器对象
    
    
    for i in lt:
    	print(i)
    	
    1. 把lt变成迭代器对象
    2. 用__next__方法迭代取值
    3. 遇到StopItera异常捕捉异常中断while循环
    
    
    # 不依赖索引迭代取值
    

    三元表达式

    三元表达式只支持双分支结构

    # x > y 条件成立时返回x值,不成立返回y值
    x = 10
    y = 20
    if x > y:
    	print(x)
    else:
    	print(y)
    	
    	
    #三元表达式
    print(x if x > y else y)
    

    列表推导式

    lt = [0,1,2,3,4]
    for i in range(10):
        lt.append(i**2)
    
    print(lt)
    
    
    # 列表推导式
    lt = [i ** 2 for i in range(10)]
    print(lt)
    

    字典生成式

    print({i: i**2 for i in range(10)})
    #{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
    
    
    # 字典生成式一般与zip(拉链函数--》列表里面包了元组)连用
    z = zip(['a', 'b', 'c', 'd'], [1, 2, 3, 4])  # 压缩方法,Python解释器的内置方法
    # for k,v in z:
    #     print(k,v)
    
    dic = {k: v ** 2 for k, v in zip(['a', 'b', 'c', 'd'], [1, 2, 3, 4])}  # 这种代码少写,能看懂就行
    print(dic)
    

    生成器

    只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码

    生成器的本质就是迭代器,同时也并不仅仅是迭代器,不过迭代器之外的用途实在是不多,所以我们可以大声地说:生成器提供了非常方便的自定义迭代器的途径。

    def func():
        yield 456  # yield会使函数func()变成生成器对象,因此他就具有__iter__方法
        print(789) # yield会停止函数,当运行下一次next才会继续运行下面的代码
        yield 101112 # 一个yield对应一个next
        print(131415)
    

    yield关键字

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

    yield的三个特性

    1. yield可以把函数变成生成器(自定制的迭代器对象,具有__iter__和__next__方法)
    2. yield可以停止函数,再下一次next再次运行yield下面的代码
    3. 有n个yield生成器就有n个元素,就可以next n次, 第n+1次next会报错

    yield和return:

    1. 相同点:两者都是在函数内部使用,都可以返回值,并且返回值没有类型和个数的限制

    2. 不同点:return只能返回一次值,终止函数;yield可以返回多次值,暂停函数,遇到下一个yield继续运行函数体代码

      range(10)
      
      1. 生成一个可迭代器对象 --- 》 我要把我的range函数变成一个可迭代对象(迭代器对象)
      2. 丢一个10进去,然后通过for循环的迭代next会丢出0,1,2,3,4,5,6,7,8,9
      
      # 有空搞这个,没空跳过
      # def range(*args, step=1):
      #     args = list(args)
      #     if len(args) == 1:
      #         count = 0
      #         while count < args[0]:
      #             yield count
      #             count += step
      #     elif len(args) == 2:
      #         while args[0] < args[1]:
      #             yield args[0]
      #             args[0] += step
      
      def range(x):
          count = 0
          while count < x:
              yield count
              count += 1
      

    生成器表达式

    • 把列表推导式的[]换成()就是生成器表达式
    • 优点:省内存,一次只产生一个值在内存中

    列表推导式相当于直接给你一筐蛋,而生成器表达式相当于给你一只老母鸡。

    # 列表推导式
    with open('52.txt', 'r', encoding='utf8') as f:
        nums = [len(line) for line in f]
    
    print(max(nums))
    
    # 生成器表达式
    with open('52.txt','r',encoding='utf8') as f:
        nums = (len(line) for line in f)
    
    print(max(nums)) # ValueError: I/O operation on closed file.
    

    递归

    函数调用函数本身,但是必须得有结束条件

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

    1. 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
    2. 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯。

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

    匿名函数

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

    f = lambda x:x+1  # lambda 参数:代码块
    print(f(1)) # 2
    

    一般不单独使用,与 max/min/map/filter/sorted联用

    max()方法工作原理:

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当做参数传给key指定的函数,然后将该函数的返回值当做判断依据
    # 从字典中取出薪资最高的人
    salary_dict = {
        'nick': 3000,
        'jason': 100000,
        'tank': 5000,
        'sean': 2000
    }
    
    print(f"max(salary_dict): {max(salary_dict)}")
    # max(salary_dict): tank
    
    def func(k):
        return salary_dict[k]
    
    
    print(f"max(salary_dict, key=func()): {max(salary_dict, key=func)}")
    # max(salary_dict, key=func()): jason
    
    # lambda与max联用
    print(
        f"max(salary_dict, key=lambda name: salary_dict[name]): {max(salary_dict, key=lambda name: salary_dict[name])}")
    # max(salary_dict, key=lambda name: salary_dict[name]): jason
    

    sorted()工作原理:

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当做参数传给第一个参数指定的函数,然后将该函数的返回值当做判断依据。
    lis = [1, 3, 2, 5, 8, 6]
    lis1 = sorted(lis)
    print(f"lis1: {lis1}") # lis1: [1, 2, 3, 5, 6, 8]
    print(f"sorted(lis,reverse=True): {sorted(lis,reverse=True)}")
    # sorted(lis,reverse=True): [8, 6, 5, 3, 2, 1]
    
    #按照薪资从大到小排序 (lammbda与sorted联用)
    salary_dict = {
        'nick': 3000,
        'jason': 100000,
        'tank': 5000,
        'sean': 2000
    }
    
    print(
        f"sorted(salary_dict, key=lambda name: salary_dict[name]): {sorted(salary_dict, key=lambda name: salary_dict[name])}")
    # sorted(salary_dict, key=lambda name: salary_dict[name]): ['sean', 'nick', 'tank', 'jason']
    

    map()工作原理:

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当做参数传给第一个参数指定的函数,然后将该函数的返回值作为map()方法的结果之一。
    # 我们想对一个列表中的某个人名做处理,可以使用map()方法。
    name_list = ['jason', 'tank', 'sean']
    
    res = map(lambda name: f"{name} sb", name_list)
    print(f"list(res): {list(res)}")
    # list(res): ['jason sb', 'tank sb', 'sean sb']
    

    filter()工作原理:

    1. 首先将可迭代对象变成迭代器对象
    2. res=next(迭代器对象),将res当做参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下。
    # 如果我们想筛选除名字中含有'sb'的名字,我们可以使用filter()方法。
    name_list = ['nick', 'jason sb', 'tank sb', 'sean sb']
    
    filter_res = filter(lambda name: name.endswith('sb'), name_list)
    print(f"list(filter_res): {list(filter_res)}")
    # list(filter_res): ['jason sb', 'tank sb', 'sean sb']
    

    内置函数

    内置函数是直接用的,属于python解释器的

    数据类型的内置函数只有数据类型本身才能使用

    掌握:

    1.abs()

    返回数字的绝对值。参数可以是整数或浮点数。如果参数为复数,则返回其大小。

    2.bytes() #解码字符

    res = '你好'.encode('utf8')  #encode转化为二进制,decode反转
    print(res)
    
    b'xe4xbdxa0xe5xa5xbd'
    
    res = bytes('你好', encoding='utf8')
    print(res)
    
    b'xe4xbdxa0xe5xa5xbd'
    

    3.chr()/ord() #chr()参考ASCII码表将数字转成对应字符;ord()将字符转换成对应的数字。

    print(chr(65))
    A
    print(ord('A'))
    65
    

    4.divmod() #函数把除数和余数运算结果结合起来。

    print(divmod(7, 2))
    (3, 1)
    print(divmod(8, 2))
    (4, 0)
    print(divmod(1+2j,1+0.5j))
    ((1+0j), 1.5j)
    

    5.enumerate() #带有索引的迭代

    l = ['a', 'b', 'c']
    for i in enumerate(l):
        print(i)
    (0, 'a')
    (1, 'b')
    (2, 'c')
    

    6.eval() #eval 可以把 list, tuple, dict 转换成str,返回来也成立;即互转。

     # 字符串转成列表
     s = '[[1,2,],[3,4,],[5,6,],[8,9]]'
     li = eval(s)
     print(li)
     print(type(s))
     print(type(li))
    
     [[1, 2], [3, 4], [5, 6], [8, 9]]
     <class 'str'>
     <class 'list'>
    
     #字符串转成字典
     s = "{1:'a',2:'b'}"
     dic = eval(s)
     print(dic)
     print(type(s))
     print(type(dic))
     
     {1: 'a', 2: 'b'}
     <class 'str'>
     <class 'dict'>
    
     #字符串转成元组
     s = '([1,2,],(3,4,),[5,6,],(8,9))'
     tu = eval(s)
     print(tu)
     print(type(s))
     print(type(tu))
    
     ([1, 2], (3, 4), [5, 6], (8, 9))
     <class 'str'>
     <class 'tuple'>
    

    7.hash() #获取取一个对象(字符串或者数值等)的哈希值。

    print(hash('test'))#字符串
    print(hash(1))#数字
    print(hash(str([1, 2, 3])))#集合
    print(hash(str(sorted({'1': 1}))))#字典
    
    3354089792780274255
    1
    -2610670198615689204
    -1768722922849136370
    
    

    了解;

    1. ascii(对象)# 如果为ascii编码则直接返回,否则转二进制
    2. all #可迭代对象内元素全为真,则返回真。False : 0、空、None、False
    3. any #可迭代对象中有一元素为真,则为真。False : 0、空、None、False
    4. bin/oct/hex #二进制、八进制、十六进制转换。
    5. dir #函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。
    6. frozenset #返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。
    7. gloabals/locals #函数会以字典类型返回当前位置的全部全局变量;函数会以字典类型返回当前位置的全部局部变量。

    更多了解:https://docs.python.org/3/library/functions.html?highlight=built#ascii

    面向过程编程

    面向过程编程是解决问题的一种思想,它与我们之后学习的面向对象编程其实没有好坏之分。面向过程编程,核心是编程二字,过程指的是解决问题的步骤,即先干什么、后干什么、再干什么、然后干什么……基于该思想编写程序就好比在设计一条流水线,面向对称编程其实是一种机械式的思维方式。

    • 优点:复杂的问题流程化,进而简单化。
    • 缺点: 可扩展性差 ; 功能与功能之间不独立 ; 调试麻烦

    分层实现功能

    • 用户功能层:实现用户具体的功能。
    • 接口层:连接数据处理层和用户功能层。
    • 数据处理层:处理数据后把结果交给接口层。

    分层实现功能的好处:当我们需要实现web端和app端的软件,我们只要把数据处理层和接口层写好,然后实现不同的用户功能层即可,web端使用web端的用户功能层,app端使用app端的用户功能层,但是接口层和数据处理层是通用的。

  • 相关阅读:
    团队作业2 需求分析与原型设计
    团队作业1
    获取公众号关注二维码url
    用户绑定公众号列表与未绑定公众号列表
    修改个人信息
    公众号登录
    idea去掉右侧小窗口代码块预览,idea去掉右侧代码预览
    微信退款 订单金额或退款金额与之前请求不一致,请核实后再试
    取消支付
    linux命令发送请求
  • 原文地址:https://www.cnblogs.com/asyouwish/p/11650683.html
Copyright © 2011-2022 走看看