zoukankan      html  css  js  c++  java
  • python笔记(11)--闭包、高阶函数和高阶内置函数

    内容目录

    • 函数中高级(闭包/高阶函数)
    • 内置函数(不常用,但是面试中经常出现)
    • 高阶内置函数(map / filter / reduce)
    • 内置模块(.py文件)

    内容回顾

    • 函数基础概念
      • 函数的基本结构

      • 参数

        • 写函数时
          • def func(a1,a2):pass
          • def func(a1,a2=None):pass
          • def func(*args,**kwargs):pass
        • 执行函数时
          • 位置参数在前 / 关键字参数在后
      • 返回值

        • 默认None
        • return
      • 函数小高级

        • 函数可以做变量

          def func():
              pass
          v1 = func
          v1()
          
          v2 = [func,func,func]
          v2[0]()
          
        • 函数可以做参数

          def func(arg):
              v2 = arg()
          
          def show():
              pass
          
          v1 = func(show)
          #注意返回值
          
        • python中以函数为作用域

          #第一题
          for item in range(10):
              pass
          print(item)		#结果为9
          
          #第二题
          item = 10
          def func():
              for item in range(10):
              	pass
          	print(item)
          func()			#结果为9
          
          #第三题
          item = 10
          def func():
              item = 2
              def inner():
                  print(item)
              for item in range(10):
              	pass
          	inner()		#此函数中item = 9
          func()			#打印9
          
          #第四题
          def func():
              for num in range(10):
                  pass
              v4 = [lambda :num+10,lambda :num+100,lambda :num+100,]
              result1 = v4[1]()
              num = 73
              result2 = v4[2]()
              print(result1,result2)
          func()		#输出109,173
          
        • lambda表达式

        • 内置函数(补充)

          • pow:指数

            v = pow(2,3)
            print(v)		#2**3,结果为8
            
          • round:保留小数点后多少位(四舍五入)

            v = round(1.325,2)	#2代表保留小数点多少位,默认取整
            print(v)		#1.32
            
        • 进制

          • bin
          • oct
          • int
          • hex
        • 其他(内置函数重点)

          • len
          • range
          • id
          • type
          • open

    补充:

    1. 数据类型中的方法到底有没有返回值

      • 无返回值

        v = [11,22,33]
        v.append(99)	#无返回值
        
      • 仅有返回值

        v = 'alec'
        result = v.split('l')
        
        v = {'k1':'v2'}
        result1 = v.get('k1')
        result2 = v.keys()
        
      • 有返回+修改数据

        v = [11,22,33]
        result = v.pop()
        
      • 常用需要记住:

        • str
          • strip,返回字符串
          • split,返回列表
          • replace,返回字符串
          • upper / lower,返回字符串
          • join,返回字符串
        • list
          • append,无
          • insert,无
          • pop,返回要删除的数据
          • remove,无
          • find / index,返回索引位置
        • dict
          • get
          • keys
          • values
          • items
    2. 如果多个函数同时执行时,内部的数据是否会混乱:

      • 函数每次运行时都会在内存中开辟一块空间,函数执行完会自动回收内存
      • 函数和函数之间调用的时候是互不影响的
      • 函数自动回收内存(符合以下条件)
        • 函数内部元素无人使用
        • 函数执行完毕

    内容详细

    1.函数中高级(闭包/高阶函数)

    1.1 函数可以做返回值

    def func():
        print("1,2,3")
    
    def bar():
        return func
    
    v = bar()
    v()			#结果为1,2,3
    
    #函数体内没有,往父级里找变量
    name = "alec"
    def func():
        print(name)
    
    def bar():
        return func
    
    v = bar()
    v()			#结果为alec
    #################################################
    name = "oldboy"
    def bar():
        name = "alec"
        def inner():
            print(name)
        return inner
    
    v = bar()
    v()         # 结果为alec
    

    1.2 闭包:

    • 为函数创建一块区域(内部变量供自己使用),为他以后执行提供数据
    name = "oldboy"
    def bar(name):
        def inner():
            print(name)
        return inner
    
    v1 = bar("alec")    #{ name=alec,return inner}	#闭包
    v2 = bar("eric")    #{ name=eric,return inner}	#闭包
    v1()         # 结果为alec,执行后回收该块内存
    v2()         # 结果为eric,执行后回收该块内存
    

    练习题:

    #第一题
    name = "oldboy"
    def bar():
        print(name)
    
    def func():
        name = "alec"
        bar()
    func()
    
    #第二题
    name = "oldboy"
    def func():
        name = "alec"
        def bar():
        	print(name)
        bar()
    func()
    
    #第三题
    name = "oldboy"
    def func():
        name = "alec"
        def base():
        	print(name)
        return base		#return返回的是base()函数地址
    base = func()		#调用func()函数,拿到return值
    base()				#return值调用函数,print输出为alec
    

    面试题:

    • 函数在何时被谁创建的

      info = []
      def func():
          print(item)
      for item in range(10):
          info.append(func)
      info[0]()
      
      info = []
      
      def func(i):
          def inner():
              print(i)
          return inner
      
      for item in range(10):
          info.append(func(item))
          
      info[0]()		#结果为0
      info[1]()		#结果为1
      info[4]()		#结果为4
      

    1.3 高阶函数

    • 把函数当做参数传递

    • 把函数当做返回值

      注意:对函数进行赋值

    1.4 总结

    • 函数执行的流程分析(函数到底是谁创建的)
    • 闭包概念:为函数创建一块区域并为其维护自己数据,以后执行时方便调用【应用场景:装饰器/SQL Alchemy源码】
      • 上面闭包的面试题搞清楚

    2.内置函数

    编码相关:

    • chr,将十进制数字转换成Unicode编码表中对应的字符串

    • ord,根据字符在Unicode编码中找到其对应的十进制

      #将十进制数字转换成Unicode编码表中对应的字符串
      v = chr(90)
      print(v)		#结果为 Z
      
      #将字符串循环输出每个字符,进行Unicode转换成十进制,然后输出二进制
      v = "中国"
      for item in v:
          item = ord(item)
          print(bin(item))
      

    高级的内置函数(map / filter / reduce)

    • map():循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),将每个函数执行的结果保存到新的列表中,并返回

      • map中第一个参数必须是函数

      • map中第二个参数必须是可迭代类型(可以被for循环的:例如list,dict,tuple,set之类的)

      • 然后将函数的返回值添加到新列表中

        • py2:直接返回列表
        • py3:返回列表的对象,不占内存,需要用时用list强转一下
        • 有返回值,原列表不做任何修改
        #修改列表中每个数据,每个数据加100
        #传统方式:
        v1 = [11,22,33]
        for index in range(0,len(v1)):
            v1[index] += 100
        print(v1)
        
        #使用map方式:
        v1 = [11,22,33]
        
        def func(arg):
            return arg + 100
        
        result = map(func,v1) #将函数的返回值添加到列表中
        print(list(result))
        
        #使用map + lambda方式:
        v1 = [11,22,33]
        result = map(lambda arg:arg + 100,v1) #将函数的返回值添加到列表中
        print(list(result))
        
      • 示例图:

        img

    • filter():循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),判断每个函数执行的True / False ,将True或False的值保存到新的列表中,并返回

      • 第一个参数必须是函数
      • 第二个参数必须是可迭代类型(可以被for循环的:例如list,dict,tuple,set之类的)
      • 然后将函数的返回值添加到新列表中
        • py2:直接返回列表
        • py3:返回列表的对象,不占内存,需要用时用list强转一下
        • 有返回值,原列表不做任何修改
      #过滤列表中所有的数字,输出结果
      #filter方式
      v1 = [11,22,33,'asdf','wqer']
      def func(arg):
          if type(arg) == int:
              return True
          return False
      result = filter(func,v1)
      print(list(result))
      
      #最终结果:
      #第一个参数func的三元运算写法
      def func(arg):
          return True if type(arg) == int else False
      
      #第一个参数func的三元运算写法
      def func(arg):
          return type(arg) == int
      
      #filter + lambda + 三元运算
      v1 = [11,22,33,'asdf','wqer']
      result = filter(lambda arg:type(arg) == int,v1)
      print(list(result))
      
      • 示例图

        img

    • reduce():

      • 必须引用模块 (import functools)
      • 第一个参数必须是函数(函数内需要两个以上的参数)
      • 第二个参数必须是可迭代类型(可以被for循环的:例如list,dict,tuple,set之类的)
      • 然后将函数的返回值添加到新列表中
        • 有返回值,原列表不做任何修改
      #计算列表中每个数的和
      #reduce方法
      import functools
      v1 = [1,2,3,4]
      def func(x,y):
          return x + y
      
      result = functools.reduce(func,v1)
      #执行时,首次执行时x,y等于列表中前两个参数,每次循环执行完,x等于之前执行的结果,y等于下一个值
      print(result)		#结果为10
      
      #reduce + lambda方式:
      import functools
      v1 = [1,2,3,4]
      
      result = functools.reduce(lambda x, y: x + y, v1)
      print(result)
      
      #将列表中每个字符串拼接起来
      import functools
      
      v1 = ["ni","hao","ma","alec"]
      
      result = functools.reduce(lambda x, y: x + y, v1)
      print(result)		#结果为nihaomaalec
      
      • 示例图

        img

    • 面试题:

      • 常用的内置函数有哪些?
      • filter / map / reduce是什么意思
      • 什么是匿名函数?(lambda表达式就是匿名函数)

    3.模块

    random模块(生成随机数)

    应用场景:生成一个随机验证码的函数

    • import 导入一个模块
    # 注意使用 chr() 方法和random.randint( min , max ),跟unicode编码对应
    # random.randint( min , max )生成随机数字
    import random
    
    def get_random_code(length=6):
        data = []
        for item in range(length):
            item = random.randint(65, 90)
            data.append(chr(item))
        return "".join(data)
    
    v = get_random_code()
    print(v)
    
    • random.shuffle方法:列表打乱顺序
    import random
    
    li = [11,22,33,44,55,66]
    random.shuffle(li)
    print(li)			# 注意,打乱的是原列表。
    

    md5加密:

    • 使用hashlib模块

    • 不可反解(但是在网上使用撞库(穷举法)可以破解:直接搜md5解密)

      import hashlib	
      
      obj = hashlib.md5()
      obj.update("123".encode("utf-8"))
      result = obj.hexdigest()
      print(result)
      
      #使用函数封装:
      import hashlib
      
      def get_md5(data):
          obj = hashlib.md5()
          obj.update(data.encode("utf-8"))
          result = obj.hexdigest()
          return result
      
      user = get_md5("123")
      print(user)
      

    md5加密加严:

    • 加密过程中使用自定义字符添加进加密算法中,无法被反解

      import hashlib
      
      def get_md5(data):
          obj = hashlib.md5("sdfjasd".encode("utf-8"))  #此md5中可自定义字符
          obj.update(data.encode("utf-8"))
          result = obj.hexdigest()
          return result
      
      user = get_md5("123")
      print(user)
      

    md5应用:

    • 用户登录

      import hashlib
      
      USER_LIST = []
      
      def get_md5(data):
          obj = hashlib.md5("sdfjasd".encode("utf-8"))
          obj.update(data.encode("utf-8"))
          result = obj.hexdigest()
          return result
      
      def register():
          print("*********用户注册*********:")
          while True:
              user = input('请创建用户名:')
              if user == "N":
                  return
              pwd = input("请创建密码:")
              USER_LIST.append({"name":user,"password":get_md5(pwd)})
      
      def login():
          print("*********用户登录*********:")
          user = input("请输入用户名:")
          pwd = input("请输入密码:")
          for item in USER_LIST:
              if item["name"] == user and item["password"] == get_md5(pwd):
                  return True
      
      register()
      result = login()
      if result:
          print("登录成功")
      else:
          print("登录失败")
      

    getpass模块(密码不显示)

    (只能在终端运行)

    import getpass					  #导入模块
    
    v = getpass.getpass("请输入密码:")	#用户输入时不显示输入内容
    if v == "456":
        print("登录成功")
    else:
        print("登录失败")
    

    总结

    • 函数
      • 基本函数结构(重点,以后98%都在用这个)
      • 高级
        • 参数
        • 闭包
      • 内置函数
      • 模块
        • random
        • hashlib
        • getpass
  • 相关阅读:
    redis从入门到放弃 -> 数据持久化
    yum怎么用?
    centos7.2系统没有eth0网卡
    redis从入门到放弃 -> 部署方案
    redis从入门到放弃 -> 简介&概念
    mysql用户权限设置
    mysql安装注意
    解决windows下的mysql匿名登陆无法使用mysql数据库的问题
    参数化测试--sheet表的应用
    整理QTP知识之1
  • 原文地址:https://www.cnblogs.com/lynlearnde/p/12909384.html
Copyright © 2011-2022 走看看