• 推导式、内置函数、高阶函数、匿名函数


      1、推导式:做一些有规律的数据结构

    列表推导式:

          普通循环模式:

          [加工后的变量 for 循环]

          示例一:print([i for i in range(1,51)])
          结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
          示例二:print([i for i in range(1,51,2)])
          结果:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]
          格式化:
          print([f"python{i}期" for i in range(1,51)])
          筛选模式:
          [加工后的变量 for循环 加工条件]
          print([i for i in range(1,51) if i > 25])
          结果:[26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
    for循环两个数的和:
    lst = []
    for i in range(2):
      for j in range(2):
        lst.append(i+j)
    print(lst)
    结果:[0, 1, 1, 2]
    列表推导式两个数的和(推导式最多建议使用三层):
    print([i + j for i in range(2) for j in range(2)])
    结果:[0, 1, 1, 2]
    字典推导式:
    print({i:i+1 for i in range(3)})
    结果:{0: 1, 1: 2, 2: 3}
    集合推导式:
    print({f"{i}:{i+1}" for i in range(3)})
    结果:{'1:2', '0:1', '2:3'}
    {加工后的变量:加工后的变量 for循环 加工条件}
    print({i:i+1 for i in range(3) if i >= 0})
    结果:{0: 1, 1: 2, 2: 3}
    推导式:用在哪?简化代码、提高可读性
    生成一些有规律的数据、生成的数据较大时建议使用生成器推导式
    for循环索引推导式:
    s = "alex,meet"
    count = 0
    for i in s:
    if i == "e":
    print(count)
    count += 1
    结果:2
       6
       7
    len索引推导式:
    print([i for i in range(len(s)) if s[i] == "e"])
    列表嵌套推导式:
    names = [['Tom','Billy','Jefferson','Andrew','Wesley','Steven','Joe'],
    ['Alice','Jill','Ana','Wendy','Jennifer','Sherry','Eva']
    ]
    写法一:
    for i in names:
    for em in i:
    if "e" in em:
    print(em)
    写法二:
    print([em for i in names for em in i if "e" in em])
    偶数推导式:
    print([i for i in range(30) if i % 3 is 0])
    结果:[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
    过滤和转大写:
    l = ['wusir','laonanhai','aa','b','taibai']
    print([i.upper() for i in l if len(i) > 3])
    结果:['WUSIR', 'LAONANHAI', 'TAIBAI']
    2、生成器表达式和列表推导式的语法上一模一样、只是把[]换成()就行了、例如将10以内所有数的平方放到一个生成器表达式中:
    gen = (i**2 for i in range(10))
    print(gen)               #得到生成器对象
    print(gen.__next__())        #生成一个数
    print(next(gen))           #再次生成一个数
    生成器表达式进行筛选:
    gen = (i for i in range(1,100) if i % 3 == 0)
    for num in gen:
    print(num)
    3、生成器表达式和列表推导式的区别?
    列表推导式比较耗内存、所有数据一次性加载到内存、而生成器表达式遵循迭代器协议、逐个产生元素。
    得到的值不一样、列表推导式得到的是一个列表、生成器表达式获取的是一个生成器
    列表推导式一目了然、生成器表达式只是一个内存地址
    无论是生成器表达式还是列表推导式、只是python提供了一个相对简单的构造方式、因为使用推导式非常简单、推导式只能构建相对复杂的并且有规律的对象
    对于没有什么规律、而且嵌套层数比较多不建议使用推导式构建
    生成器的惰性机制:生成器只有在访问的时候才取值、
    4、内置函数:python写了很多功能避免重复造轮子
    一带而过:
    all()  #判断元素是否都为true
    any()  #判断元素是否有一个是true就是true
    bytes() #字符串转字节
    callable("你好")  #判断是否可调用
    chr()  #根据当前编码查看对应的内容
    complex()  #查看复数
    divmod()  #获取是元组、第一个是商、第二个是余数
    eval()  #禁用
    exec()  #禁用
    frozenset()  #冻结集合
    globals()
    hash()  #有值是不可变的数据类型
    help()  #查看方法的帮助信息
    id()   
    input()
    int()
    iter()
    locals()
    next()
    oct()  #十进制转成八进制
    bin()  #十进制转成二进制
    hex()  #十进制转成十六进制
    print(int("0x1e",16))  #十六进制转成十进制
    ord()  #根据值查看当前编码
    pow()  #幂
    repr()  #原形毕露
    round()  #保留小数位
    重点记住:
    abs()  #绝对值
    format()  #格式化
    enumerate()  #枚举、自动获取元素下标、自动计数
    filter()
    map()
    max()
    min()
    open()
    range()
    print()
    len()
    list()
    dict()
    str()
    float()
    reversed()
    set()
    sorted()  #排序
    sum()
    tuple()
    type()
    zip()
    dir()  #查看当前对象都有什么方法
    未来会用:
    classmethod()
    delattr()
    getattr()
    hasattr()
    issubclass()
    isinstance()
    object()
    property()
    selattr()
    staticmethod()
    super()
    5、高阶函数:
    filter(规则函数,可迭代对象)、
    map(规则函数,可迭代对象,可迭代对象)、
    max()、
    min()、
    reversed(可迭代对象)、
    sorted(可迭代对象,key = 规则函数)、
    reduce(累加函数,可迭代对象)、
    zip()、
    6、匿名函数,顾名思义就是没有名字的函数,那么什么函数没有名字呢?这个就是我们以后面试或者工作中经常用匿名函数 lambda,也叫一句话函数。
    现在有一个需求:你们写一个函数,此函数接收两个int参数,返回和值。
    def func(a,b):
        return a+b
    print(func(3,4))
    那么接下来我们用匿名函数完成上面的需求:
    func = lambda a,b: a+b
    print(func(3, 4))  # 7
    语法:

    ​ 1)此函数不是没有名字,他是有名字的,他的名字就叫做lambda

    ​ 2)lambda 是定义匿名函数的关键字,相当于函数的def.

    ​ 3)lambda 后面直接加形参,形参加多少都可以,只要用逗号隔开就行。  

    ​ 4)返回值在冒号之后设置,返回值和正常的函数一样,可以是任意数据类型。(但是想要返回多个元素要以容器的形式返回)

    ​ 5)匿名函数不管多复杂.只能写一行.且逻辑结束后直接返回数据

    写匿名函数:接收一个可切片的数据,返回索引为0与2的对应的元素(元组形式)。

    func = lambda x:(x[0],x[2])
    print(func('afafasd'))
    7、匿名函数三元表达式:
    func = lambda x,y: x if x > y else y
    print(func(3,100))
    结果:100
    8、匿名函数lambda和有名函数def:
    f = lambda a,b:a + b
    print(f(1,2))
    # 结果3
    def func(a,b):
    c = a + b
    return c
    print(func(1,2))
    # 结果3
    lambda和def是一样的、
    a,b和(a,b)是一样的
    :a + b和return a + b是一样的
    冒号前面叫做形参、冒号后面叫做返回值
    形参可以接受位置参数、动态位置、默认、动态关键字参数、形参不可不写
    返回值只能返回一个数据、返回值必须写
    返回值是多个时用括号包起来
    print(f.__name__)--查看函数名
    9、lambda函数举例:
    # g = [lambda i:i+1 for i in range(3)]  #首先这是列表推导式、循环三圈得到三个匿名函数lambda、例如定义是L、第二圈还是L、第三圈还是L、函数体中存的是代码、也可以把for i定义成for j、整个推完之后有三个函数的内存地址定义为g、
    # print([em(3) for em in g])         #然后循环三个内存地址定义em、加括号运行、命名参数3、得到结果3+1=4、第二圈还是4、第三圈还是4
    #上面两行代码拆解:
    lst = []
    for i in range(3): #for循环0到3
    def func(i): #形参是i也就是0、1、2
    return i + 1 #返回值是循环的每个值加1
    lst.append(func) #往空列表里面增加func函数的内存地址
    print(lst) #打印出lst列表里面的3个func函数的内存地址
    # 结果:[<function func at 0x00000000001E2EA0>, <function func at 0x0000000001E9AB70>, <function func at 0x0000000001E9AA60>]

    new_lst = [] #新建空列表new_lst
    for em in lst: #循环lst列表里面的3个func函数的内存地址
    new_lst.append(em(3)) #空列表里面增加3个func函数的内存地址运行结果、说白了在调用func、但是func函数需要参数i、所以增加em里面增加一个参数3
    print(new_lst) #打印new_lst列表
    # 结果:[4, 4, 4]
    10、lambda函数举例二:
    # g = (lambda i:i+1 for j in range(3))
    # print([em(3) for em in g])
    #上面两行代码拆解:
    def foo():
    for j in range(3):
    def func(i):
    return i + 1
    yield func
    g = foo()
    # print(g) #得到生成器
    # print(next(g)) #得到函数的内存地址

    lst = []
    for i in g:
    lst.append(i(3))
    print(lst)
    结果:[4,4,4]
    11、小括号是生成器推导式、中括号是列表推导式
    12、lambda函数举例三:
    # g = [lambda :i+1 for i in range(3)]
    # print([em() for em in g])
    #上面两行代码拆解:
    g = []
    for i in range(3):
    def func():
    return i + 1
    g.append(func)
    print(g)

    new_lst = []
    for em in g:
    new_lst.append(em())
    print(new_lst)
    结果:[3,3,3]
    13、lambda函数举例四:
    g = (lambda :i+1 for i in range(3))
    print([em() for em in g])
    #上面两行代码拆解:
    def foo():
    for i in range(3):
    def func():
    return i + 1
    yield func
    g = foo()

    lst = []
    for i in g:
    lst.append(i())
    print(lst)
    结果:[1,2,3]
    14、lambda函数举例五:
    g = [lambda x:x*i for i in range(3)]
    for j in [2,10]:
    g1 = (em(3) for em in g)
    print([e+j for e in g1])
    结果:[16, 16, 16]
    15、lambda函数举例六:
    lst = []    #[func,func,func]
    for i in range(3):
    def func(x):
    return x * i #3*2
    lst.append(func)

    for j in [2,10]:
    def g1(): #循环产生两个生成器、第二个生成器10覆盖第一个的2
    for em in lst:
    yield em(3) #func(3)

    new_lst = []
    for e in g1():
    new_lst.append(e + j) #g1是6、e是6、j是10
    print(new_lst)
    # 结果:[16, 16, 16]
    16、模拟高阶函数filter过滤:
    filter函数是把列表中的值所有的都筛选一遍最后在得到一个值(列表)
    lst = [1,2,3,4,54,65,7,8]
    def foo(x): #规则函数
    return x > 4 #判断的是True和False

    def f(func,iter): #filter
    lst = [] #[54,65,7,8]
    for i in iter:
    if func(i):
    lst.append(i)
    return lst
    print(f(foo,lst))
    # 结果:[54, 65, 7, 8]
    17、高阶函数filter:
    lst = [1,2,3,4,54,65,7,8]
    print(list(filter(lambda x:x > 4,lst)))
    18、#过滤掉年龄大于等于17的
    lst = [{'id':1,'name':'alex','age':18},
    {'id':1,'name':'wusir','age':17},
    {'id':1,'name':'taibai','age':16},]
    print(list(filter(lambda x:x["age"] >= 17,lst)))
    结果:[{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}]
    19、过滤掉名字长度大于等于5的(过滤出是拿到、过滤掉是不要)
    lst = [{'id':1,'name':'alex','age':18},
    {'id':1,'name':'wusir','age':17},
    {'id':1,'name':'taibai','age':16},]
    print(list(filter(lambda x:len(x["name"]) >= 5,lst)))
    # 结果:[{'id': 1, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'taibai', 'age': 16}]
    20、高阶函数map映射--将可迭代对象中每个元素执行函数功能:
    map函数是装一个列表依次处理得到的还是一个列表,跟原先的列表顺序一样、只不过每个元素被处理了
    转成字符串:
    lst = [1,2,3,4,5,6,8,9]
    print(list(map(str,lst)))
    # 结果:['1', '2', '3', '4', '5', '6', '8', '9']
    合并求列表和:
    lst1 = [1,2,3]
    lst2 = [3,2,1]
    print(list(map(lambda x,y:x + y,lst1,lst2)))
    结果:[4, 4, 4]
    21、sorted排序函数:
    lst = [1,2,3,4,65,7]
    print(sorted(lst)) #新建列表
    结果:[1, 2, 3, 4, 7, 65]

    lst.sort()
    print(lst) #原地修改
    结果:[1, 2, 3, 4, 7, 65]
    print(sorted("alex,mdsb"))              #升序
    结果:[',', 'a', 'b', 'd', 'e', 'l', 'm', 's', 'x']
    print(sorted("alex,mdsb",reverse=True)) #降序
    结果:[',', 'a', 'b', 'd', 'e', 'l', 'm', 's', 'x']
    排键:
    dic = {1:"a",3:"c",2:"b"}
    print(sorted(dic))
    结果:[1, 2, 3]
    四大名著排序:
    lst = ['天龙八部','西游记','红楼梦','三国演义']
    print(sorted(lst,key = len)) #key = 排序规则
    结果:['西游记', '红楼梦', '天龙八部', '三国演义']
    lst = [{'id':1,'name':'alex','age':18},
    {'id':2,'name':'wusir','age':17},
    {'id':3,'name':'taibai','age':16},]
    print(sorted(lst,key=lambda x:x['age'],reverse=True))
    # 结果:[{'id': 1, 'name': 'alex', 'age': 18}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 3, 'name': 'taibai', 'age': 16}]
    22、max最大值:
    print(max([1,2,3,4,5,6,-9,10,-22],key=abs))
    结果:-22
    23、min最小值:
    print(min([1,2,3,4,5,6,-9,10,-22],key=abs))
    结果:1
    24、reduce累计算:
    reduce函数是可以把完整的序列合并到一块儿最终得到一个值
    累乘:
    from functools import reduce
    lst = [1,2,3,4,5]
    print(reduce(lambda x,y:x*y,lst))
    结果:120
    25、zip拉链:
    lst1 = [1,2,3,4,5]
    lst2 = [5,4,3,2,1]
    print(list(zip(lst1,lst2)))
    结果:[(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]
    26、print加参数分隔符
    print("alex","wusir","太亮",sep="|")
    结果:alex|wusir|太亮
    print("alex","wusir","太亮",sep="|",end="")
    print("meet")
    结果:alex|wusir|太亮meet
    作业题:
    三次登陆锁定:
    """
    四.用代码实现三次用户登录及锁定(选做题,这是一个单独的程序)
    项目分析:
    一.首先程序启动,显示下面内容供用户选择:
    1.注册
    2.登录
    a.用户选择登录的时候,首先判断用户名在userinfo.txt表中存在不在,存在就不能进行注册
    b.当注册的用户名不存在的时候将用户名和密码写入到userinfo.txt文件中
    c.用户选择登录的时候,判断用户输入的账号和密码是否userinfo.txt存储的一致
    d.用户名和密码一致就终止循环,并提示用户登录成功!
    e.用户名和密码不一致,只有三次登录机会,三次过后提示用户名被锁定,请联系管理员!并终止循环
    f.当用户名错误三次,再次运行程序.登录锁定的账号继续提示用户名被锁定,请联系管理员!
    """
    # 结束标识
    quite_flag = False # ------------------------------2、

    # 错误登录次数 #------------------------------------3、
    login_fail = 0

    # 登录功能
    def login(): # -----------------------------5、
    """
    登录
    :return:
    """
    while True:
    global login_flag # 定义全局登录状态
    global quite_flag # 定义全局结束标识
    global login_fail # 定义全局登录次数
    user_name = input ( "请输入登录用户名:" )
    password = input ( "请输入密码:" )
    if user_name in userinfo_dic:
    login_flag = True if password == userinfo_dic[user_name] else False
    if userinfo_dic[user_name + "locked"] == "True":
    login_flag = False
    print ( "用户名被锁定,请联系管理员!" )
    break
    if login_flag:
    print ( "登陆成功!" )
    quite_flag = True
    break
    else:
    login_fail += 1
    if login_fail == 3:
    modif_userinfo(user_name,userinfo_dic[user_name],str(True))
    quite_flag = True
    print("用户名被锁定,请联系管理员!")
    break
    else:
    print("用户账号或密码错误,请重新输入")
    else:
    print("用户名不存在!请重新输入!")



    # 注册功能
    def register():
    """
    注册
    :return:
    """
    while True:
    user_name = input ( "请输入用户名(不能有特殊字符):" )
    password = input ( "请输入密码长度要在6~14个字符之间:" )
    if user_name not in userinfo_dic:
    if user_name.isalnum () and 5 < len ( password ) < 15:
    write_userinfo ( user_name, password )
    print ( "注册成功!" )
    global login_fail # 声明全局错误登录次数
    login_fail = 0
    global login_flag # 声明全局登录状态
    login_flag = True #改成登录状态True
    break #改成break相当于注册完毕了
    else:
    print ( "输入错误,请重新输入" )
    else:
    print ( "用户名已存在!请重新输入!" )


    def quite():
    """
    退出
    :return:
    """
    global quite_flag
    quite_flag = True


    # 定义用户读取文件信息功能
    def read_userinfo(path_add: str):
    """
    读取用户信息
    :return:
    """
    with open ( path_add, "a+", encoding="utf-8" ) as f:
    global userinfo_dic
    f.seek ( 0 )
    for i in f:
    if i != " " and i != "" and i is not None:
    userinfo_dic[i.split ( ":" )[0].strip ()] = i.split ( ":" )[1].strip ()
    userinfo_dic[i.split ( ":" )[0].strip () + "locked"] = i.split ( ":" )[2].strip ()


    # 定义用户写入文件信息功能
    def write_userinfo(user_name: str, password: str):
    """
    写入用户信息
    :param user_name:
    :param password:
    :return:
    """
    with open ( path_add, "a", encoding="utf-8" ) as f1: #a模式、防止文件不存在时报错
    f1.write ( f" {user_name}:{password}:False" ) #第一次注册往字典里面添加状态没有被锁定
    f1.flush ()
    global login_fail # 定义全局错误登录次数
    userinfo_dic[user_name] = password # 字典是可变数据类型、在局部使用全局进行修改不用使用global、往字典里面增加键值对
    userinfo_dic[user_name + "locked"] = str ( False ) # 往用户信息字典里面建立用户锁定状态


    # 定义用户锁定信息功能
    def modif_userinfo(user_name: str, password: str, locked: str):
    """
    锁定用户信息修改
    :param user_name:
    :param password:
    :param locked:
    :return:
    """
    with open ( path_add, "r", encoding="utf-8" ) as f4,
    open ( path_add.replace ( ".txt", "1.txt" ), "w", encoding="utf-8" ) as f5:
    for i in f4:
    if i != " " and i.split ( ":" )[0].strip () == user_name:
    i = f"{user_name}:{password}:{locked} "
    f5.write ( i )
    f5.flush ()
    global userinfo_dic
    userinfo_dic[user_name] = password
    userinfo_dic[user_name + "locked"] = locked
    import os
    import time
    os.rename ( path_add, path_add.replace ( ".txt", str ( time.time () ) + ".bak" ) )
    os.rename ( path_add.replace ( ".txt", "1.txt" ), path_add )
    global login_fail # 定义全局登录次数
    login_fail = 0


    # 组成字典容器
    choose_dic = {"1": register,
    "2": login,
    }

    # 新建已注册的用户账户和密码字典形式:
    userinfo_dic = dict ()

    # 定义文件地址信息存储位置变量
    path_add = "userinfo_single.txt"

    # 读取一下已经注册的用户和密码
    read_userinfo ( path_add )

    # 登陆信息提示:#-----------------------------------1、
    print ( """1.注册
    2.登录""" )

    # 主程序 #---------------------------------------4、
    while not quite_flag:
    choose = input ( "请选择您要进行的操作对应的序号:" )
    choose_dic[choose] () if choose in choose_dic else print ( "输入错误,请重新输入!" )
    else:
    print ( "结束" )
    # 1、用列表推导式做下列小题
    lst = ["alex","wusir","太白","宝元"]
    # 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
    print([i.upper() for i in lst if len(i) > 3])
    # 2、求[{x:y}]其中x是0-5之间的偶数组成的元组的,y是0-5之间的奇数组成的元组
    print([{tuple([i for i in range(0,6,2)]):tuple([i for i in range(1,6,2)])}])
    # 3、求3,6,9 组成的列表结果: M = [[1,2,3],[4,5,6],[7,8,9]]
    print([[i for i in range(1,4)],[i for i in range(4,7)],[i for i in range(7,10)]])
    # print([i-2,i-1,i] for i in [3,6,9])?????????????????????????这道题我不会做太难了
    # 4、求出50以内能被3整除的数的平方,并放入到一个列表中。
    print([i**2 for i in range(51) if i // 3])
    # 5、构建一个列表:['python1期', 'python2期', 'python3期', 'python4期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']
    print(["python%s期" %i for i in range(1,11)])
    # 6、构建一个列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
    # 7、构建一个列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    print([i for i in range(20) if i % 2 == 0])
    # 8、有一个列表l1 = ['alex', 'WuSir', '老男孩', '太白']将其构造成这种列表
    # ['alex0', 'WuSir1', '老男孩2', '太白3']
    print(['%s%s' %(l1,i) for i,l1 in enumerate(l1)])
    # for循环形式:
    # l1 = ['alex','Wusir','老男孩','太白']
    # for i,em in enumerate(l1):
    # print(em + str(i))
    # 9、有以下数据类型:
    x = {
    'name':'alex',
    'Values':[{'timestamp':1517991992.94,
    'values':100,},
    {'timestamp': 1517992000.94,
    'values': 200,},
    {'timestamp': 1517992014.94,
    'values': 300,},
    {'timestamp': 1517992744.94,
    'values': 350},
    {'timestamp': 1517992800.94,
    'values': 280}
    ],}
    # 将上面的数据通过列表推导式转换成下面的类型:[[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]
    print([[i["timestamp"],i["values"]] for i in x["Values"]])
    # 10、构建一个列表,列表里面是三种不同尺寸的T恤衫,每个尺寸都有两个颜色(列表里面的元素为元组类型)。
    # colors = ['black', 'white']
    # sizes = ['S', 'M', 'L']
    print(list(zip(colors,sizes)))
    # 11、构建一个列表,列表里面的元素是扑克牌除去大小王以后,所有的牌类(列表里面的元素为元组类型)。
    # l1 = [('A','spades'),('A','diamonds'), ('A','clubs'), ('A','hearts')......('K','spades'),('K','diamonds'), ('K','clubs'), ('K','hearts') ]
    # 12、看代码求结果(面试题):
    # v = [i % 2 for i in range(10)]
    # print(v)
    # 结果:[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
    # v = (i % 2 for i in range(10))
    # print(v)
    # 结果:<generator object <genexpr> at 0x0000000002152D00> #生成器内存地址
  • 相关阅读:
    NSlog 对于新手的一点技巧和用法.
    iOS7+ 扫描二维码和条形码实现 耗时操作
    关于iOS block循环引用的一点理解
    Xcode 快捷开发的几个插件
    在Mac下面删除所有的.svn文件
    一个textView 预留空白的问题
    Supporting Multiple iOS Versions and Devices
    Building an iOS Universal Static Library
    iOS Library With Resources
    iOS开发长文--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总
  • 原文地址:https://www.cnblogs.com/zhang-da/p/11633267.html
Copyright © 2020-2023  润新知