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
posted @ 2020-05-18 11:05  薛定谔的猫儿  阅读(90)  评论(0编辑  收藏  举报