#!/usr/bin/env python
# -*- coding:utf-8 -*-
# # 一些文章
# https://www.cnblogs.com/Vae1242/p/6944338.html
# python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解 - 天意凉 - 博客园
# https://www.cnblogs.com/tianyiliang/p/7811041.html
# ********************day20_函数的闭包 与 装饰器 *******************
# ********************day20_函数的闭包 与 装饰器 *******************
# ********************day20_函数的闭包 与 装饰器 *******************
# =====>>>>>>内容概览
# =====>>>>>>内容概览
# =====>>>>>>内容概览
'''
# # 0、1 重要知识点
# # # 装饰器:本质就是函数,功能是为了给其他函数添加附加功能
# # # 原则:
# # # # 1、不修改被修饰函数的源代码
# # # # 2、不修改被修饰函数的调用方式
#
# # 0、2 装饰器的知识储备:
# # # 装饰器 = 高阶函数+ 函数嵌套 + 闭包
# # 1、上一节回顾
# # # 、不使生成器执行函数
# # # 执行效率低下
# #
# # 2、使用生成器 及生成器的运行3种方式
# # # 执行生成器的方式:
# # # 1、next(t)
# # # 2、t.__next__()
# # # 3、t.send( value )
# #
# # 3、三元运算
# # 4、生成器
# # 5、列表解析 与 生成器表达式
# # 6、生成器取值只能取一次(对于某个变量)
# # 7、装饰器的定义
# # # 不修改foo源代码
# # # 不修改foo调用方式
# # 8、高阶函数
"""
# # # 高阶函数的定义:
# # # 1、函数接受的参数是一个函数名
# # # 2、函数的返回值是一个函数名
# # # 3、满足上述条件任意一个,都可以称之为高阶函数
# # 9、计算foo的运行时间
# # # 满足高阶函数的第一个定义,接受的参数是一个函数名
# # 10、尝试在满足装饰器函数的定义下,计算foo的时间
# # # 方式:高阶函数实现
# # 11、满足高阶函数的第2个条件,返回值是一个函数
# # 12、对函数foor计算运行时间
# # # 这里满足了高阶函数的定义下,对函数foo进行计算时间,
# # # 但是,多执行了一次foo函数,因为在test计算时间的时候,需要执行函数
# # 13、实例:使用高阶函数来模拟装饰器函数,失败
# # 14、函数的嵌套与函数调用
# # 15、函数闭包
# # # 函数闭包是函数调用的一种; 其中,“闭”就是封装变量的意思, 一层一层的向内封装
# # 16、装饰器的实现的过程
# # 17、装饰器的实现方式
# # # 实现过程:写好函数,在相关的函数前面使用 @相关函数名 即可
# # # @timmer 就相当于 test=timmer(test)
# # 18、关于返回值的问题
# # 19、知识补充--解压順序
# # # 内容根据顺序,一次赋值
# # 20、初步装饰器函数多个参数问题
# # 21、最终装饰器函数多个参数问题
# # 22、解压顺序
# # # a,*_,b= l
# # # 格式:变量1, *中间变量2,变量3
# # # 其中,如果中间变量2是“_”下划线的话,那么一般代表值是不要的
# # 23、带有验证功能的装饰器(多次登录)
# # 24、带有验证功能的装饰器(一次登录)
# # # 解决上面例子中,需要重复登录的问题
# # 25、带有参数验证功能的装饰器
'''
# print("分割线".center(80,"*"))
# **************************************分割线***************************************
# **************************************分割线***************************************
# **************************************分割线***************************************
# # 0、1 重要知识点
# # # 装饰器:本质就是函数,功能是为了给其他函数添加附加功能
# # # 原则:
# # # # 1、不修改被修饰函数的源代码
# # # # 2、不修改被修饰函数的调用方式
#
# # 0、2 装饰器的知识储备:
# # # 装饰器 = 高阶函数+ 函数嵌套 + 闭包
# 01
# 01
# 01
# # 1、上一节回顾
# # # 、不使生成器执行函数
# # # 执行效率低下
# #
#
# def run():
# i=0
# print("from run!---%s"%i)
# i = i + 1
# print("from run!---%s" % i )
# i = i + 1
# print("from run!---%s" % i )
# i = i + 1
# print("from run!---%s" % i )
#
# run()
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # from run!---0
# # from run!---1
# # from run!---2
# # from run!---3
# #
# # Process finished with exit code 0
# # 2、使用生成器 及生成器的运行3种方式
# # # 执行生成器的方式:
# # # 1、next(t)
# # # 2、t.__next__()
# # # 3、t.send( value )
# #
#
# def test():
# i=0
# print("test")
# yield i
#
# i = i + 1
# print("from test!---%s"%i)
#
# yield i
# i = i + 1
# print("from test!---%s"%i)
#
# yield i
# i = i + 1
# print("from test!---%s"%i)
#
# t = test() # 注意这里是没有执行程序的
# next(t)
# next(t)
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # test
# # from test!---1
# #
# # Process finished with exit code 0
# # 3、三元运算
# age =10
# res = True if age>10 else False
# print(res)
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # False
# #
# # Process finished with exit code 0
# # 4、生成器
# def test():
# for i in range(4):
# yield i
# t = test() # 只是拿到了生成器的地址,并没有执行
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# #
# # Process finished with exit code 0
# # 5、列表解析 与 生成器表达式
# 列表解析
# a = sum( [i for i in range(10000000)] ) # 内存占用大,机器容易卡死
# print(a)
# # 生成器表达式
# b = sum( (i for i in range(10000000)) ) # 几乎不占内存
# print(b)
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # 49999995000000
# # 49999995000000
# #
# # Process finished with exit code 0
# # 6、生成器取值只能取一次(对于某个变量)
# def test():
# for i in range(4):
# yield i
# t = test()
#
# for i in t:
# print(i)
#
# t1 = (i for i in t)
# print(list(t1)) # 这里 空,是因为生成器的值被取完了
#
# x = test() # 将生成器给另外一个变量,
# x1 = ( i for i in x)
# x2 = ( i for i in x) # 这里 空,是因为生成器的值被取完了
#
# print(list(x1))
# print(list(x2))
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # 0
# # 1
# # 2
# # 3
# # []
# # [0, 1, 2, 3]
# # []
# #
# # Process finished with exit code 0
# 02
# 02
# 02
# # 7、装饰器的定义
# # # 不修改foo源代码
# # # 不修改foo调用方式
# #
#
# # 8、高阶函数
"""
# # # 高阶函数的定义:
# # # 1、函数接受的参数是一个函数名
# # # 2、函数的返回值是一个函数名
# # # 3、满足上述条件任意一个,都可以称之为高阶函数
"""
# # 9、计算foo的运行时间
# # # 满足高阶函数的第一个定义,接受的参数是一个函数名
# import time
# def foo():
# time.sleep(2)
# print("foo function !")
#
# def test(func):
# start_time = time.time()
# func()
# stop_time = time.time()
# print("函数的运行时间是%s" %(stop_time - start_time))
# test(foo)
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # foo function !
# # 函数的运行时间是2.0001144409179688
# #
# # Process finished with exit code 0
# # 10、尝试在满足装饰器函数的定义下,计算foo的时间
# # # 方式:高阶函数实现
# #
#
# import time
# def foo():
# time.sleep(2)
# print("foo function !")
#
# def test(func):
# start_time = time.time()
# func()
# stop_time = time.time()
# print("函数的运行时间是%s" %(stop_time - start_time))
# test(foo)
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # foo function !
# # 函数的运行时间是2.0001144409179688
# #
# # Process finished with exit code 0
# # 11、满足高阶函数的第2个条件,返回值是一个函数
# def foo():
# print('from the foo')
# def test(func):
# return func
#
# '''
# # 这里实现了在满足装饰器函数的条件下,高阶函数的第二个条件下,对foo函数的调用
# res=test(foo)
# # print(res)
# res()
#
# '''
# foo=test(foo)
# foo()
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # from the foo
# #
# # Process finished with exit code 0
# # 12、对函数foor计算运行时间
# # # 这里满足了高阶函数的定义下,对函数foo进行计算时间,
# # # 但是,多执行了一次foo函数,因为在test计算时间的时候,需要执行函数
# import time
# def foo():
# time.sleep(2)
# print("foo function !")
#
# def test(func):
# start_time = time.time()
# func()
# stop_time = time.time()
# print("函数的运行时间是%s" %(stop_time - start_time))
# return func
#
# foo = test(foo)
# foo()
#
# #
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # foo function !
# # 函数的运行时间是2.0001144409179688
# # foo function !
# #
# # Process finished with exit code 0
# # 13、实例:使用高阶函数来模拟装饰器函数,失败
# import time
# def foo():
# time.sleep(2)
# print("foo function !")
#
# # 没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能
# def timer(func):
# start_time=time.time()
# return func
# stop_time = time.time()
# print('函数运行时间是 %s' % (stop_time-start_time))
#
# foo=timer(foo)
# foo()
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # foo function !
# #
# # Process finished with exit code 0
# 04
# 04
# 04
# print("函数闭包".center(80,"*"))
# **************************************函数闭包**************************************
# **************************************函数闭包**************************************
# **************************************函数闭包**************************************
# # 14、函数的嵌套与函数调用
# def bar():
# print("from bar")
# foo() # 这个是函数的调用,不属于函数的嵌套
# def foo():
# print("from foor!")
# def test(): # 这个叫函数嵌套
# print("from test!")
#
# # 15、函数闭包
# # # 函数闭包是函数调用的一种; 其中,“闭”就是封装变量的意思, 一层一层的向内封装
# # # 下面,father封装了son,son封了grandson
# def father(name):
# print("from father %s"%name)
# def son():
# print("from son %s" % name)
# def grandson():
# print("from grandson %s" % name)
# grandson()
# son()
# father("小伙")
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # from father 小伙
# # from son 小伙
# # from grandson!
# #
# # Process finished with exit code 0
# 05
# 05
# 05
# print("装饰器的实现".center(80,"*"))
# *************************************装饰器的实现*************************************
# *************************************装饰器的实现*************************************
# # 16、装饰器的实现的过程
#
# import time
# def timer(func): # func = test
# def wrapper():
# start_time = time.time()
# func() # func相当于拿到了test的运行地址,func()就是运行test()
# stop_time = time.time()
# print("运行的时间是 %s "%(stop_time - start_time ))
# return wrapper
#
# def test():
# time.sleep(2)
# print("test 运行完毕!!")
#
# # test() # 在没有装饰器的情况下对test函数的运行
# # 使用装饰
# res = timer(test) # 返回的是wrapper的地址
# res() # 执行的是wrapper()
#
# # 接下来满足装饰器条件,不更改函数的调用方式
# test = timer(test)
# test()
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # test 运行完毕!!
# # 运行的时间是 2.0001144409179688
# # test 运行完毕!!
# # 运行的时间是 2.0001139640808105
# #
# # Process finished with exit code 0
# # 17、装饰器的实现方式
# # # 实现过程:写好函数,在相关的函数前面使用 @相关函数名 即可
# # # @timmer 就相当于 test=timmer(test)
# #
#
# import time
# def timer(func): # func = test
# def wrapper():
# start_time = time.time()
# func() # func相当于拿到了test的运行地址,func()就是运行test()
# stop_time = time.time()
# print("运行的时间是 %s "%(stop_time - start_time ))
# return wrapper
#
# @timer # @ 解释:test=timmer(test)
# def test():
# time.sleep(2)
# print("test 运行完毕!!")
#
# test()
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # test 运行完毕!!
# # 运行的时间是 2.0001144409179688
# #
# # Process finished with exit code 0
# 06
# 06
# 06
# ***********************************装饰器的加上一些参数***********************************
# 给装饰器加上参数
# # 18、关于返回值的问题
# import time
# def timer(func): # func = test
# def wrapper():
# start_time = time.time()
# """
# 这里解决返回值的问题
# """
# res = func() # func相当于拿到了test的运行地址,func()就是运行test()
# stop_time = time.time()
# print("运行的时间是 %s "%(stop_time - start_time ))
# return res
# return wrapper
#
# @timer # @ 解释:test=timmer(test)
# def test():
# time.sleep(1)
# print("test 运行完毕!!")
# return '这是test的返回值'
#
# res = test()
# print(res)
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # test 运行完毕!!
# # 运行的时间是 1.0000569820404053
# # 这是test的返回值
# #
# # Process finished with exit code 0
# # 19、知识补充--解压順序
# # # 内容根据顺序,一次赋值
# a,b,c,s,l,se,yuan = (1,2,3,"string",[11,22,"sss"],{"name":"tome","age":23},("set",999))
# print(a,b,c,s,l,se,yuan )
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # 1 2 3 string [11, 22, 'sss'] {'name': 'tome', 'age': 23} ('set', 999)
# #
# # Process finished with exit code 0
# # 20、初步装饰器函数多个参数问题
# import time
# def timer(func): # func = test
# def wrapper(name,age):
# start_time = time.time()
# """
# 这里解决返回值的问题
# """
# res = func(name,age) # func相当于拿到了test的运行地址,func()就是运行test()
# stop_time = time.time()
# print("运行的时间是 %s "%(stop_time - start_time ))
# return res
# return wrapper
#
# @timer # @ 解释:test=timmer(test)
# def test(name,age):
# time.sleep(1)
# print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))
# return '这是test的返回值'
#
# res = test("aaaaa",11)
# print(res)
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # test函数运行完毕,名字是【aaaaa】 年龄是【11】
# # 运行的时间是 1.0050575733184814
# # 这是test的返回值
# #
# # Process finished with exit code 0
# # 21、最终装饰器函数多个参数问题
# import time
# def timer(func): # func = test("aaaaa",11)
# """
# 这里解决多个返回值的问题
# """
# def wrapper(*args,**kwargs):
# start_time = time.time()
# # 在这个位置上面添加一定的修饰功能
#
# # ===========>>>>>原函数的内容<<<<<===========
# # 获取原来的代码并且拿到它的返回值
# res = func(*args,**kwargs) # func相当于拿到了test的运行地址,并且运行,同时获取它的返回值
# # ===========>>>>>原函数的结束<<<<<===========
#
# # 在这个位置下面添加一定的修饰功能
# stop_time = time.time()
# print("运行的时间是 %s "%(stop_time - start_time ))
# return res # 将获取到的返回值进行返还
# return wrapper
#
# @timer # @ 解释:test=timmer(test)
# def test(name,age):
# time.sleep(1)
# print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))
# return '这是test的返回值'
#
# res = test("aaaaa",11)
# print(res)
#
# #
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # test函数运行完毕,名字是【aaaaa】 年龄是【11】
# # 运行的时间是 1.0000572204589844
# # 这是test的返回值
# #
# # Process finished with exit code 0
# 08
# 08
# 08
# **********************************补充内容:解压顺序***********************************
# # 22、解压顺序
# # # a,*_,b= l
# # # 格式:变量1, *中间变量2,变量3
# # # 其中,如果中间变量2是“_”下划线的话,那么一般代表值是不要的
# #
#
# l = [10,3,2,4,8,7,900]
# a,*_,b= l
# r,*zhongjian,u= l
# # c,d,*m,q,w= l # 报错,没有这种用法,只能去开头+中间+结尾
#
# print(r,zhongjian,u)
# print(a,b)
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # 10 [3, 2, 4, 8, 7] 900
# # 10 900
# #
# # Process finished with exit code 0
# 09
# 09
# 09
# *********************************函数闭包为函数加上认证功能**********************************
# *********************************函数闭包为函数加上认证功能**********************************
# 函数闭包为函数加上认证功能
# # 23、带有验证功能的装饰器(多次登录)
# def auth_func(func):
# def wrapper(*args,**kwargs):
# usrname = input("用户名:").strip() # 移除收尾字符的空格
# passwd = input("密码:").strip() # 移除收尾字符的空格,这里似乎不太正确,不应该家strip
# if usrname=="产品经理"and passwd=="123":
# res = func(*args,**kwargs)
# else:
# print("用户名或者密码错误")
# return res
# return wrapper
#
# # def home():
# # pass # ???看视频
# @auth_func
# def home(name):
# print("欢迎回家,%s"%name)
# @auth_func
# def shopping_car(name):
# print("%s的购物车里有[%s, %s, %s]"%( name,"奶茶","水瓶","苹果"))
#
# def order():
# pass
#
# def index():
# print("欢迎来到京东主页!")
#
# index()
# home("产口经理")
# shopping_car("产口经理")
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # 欢迎来到京东主页!
# # 用户名:产品经理
# # 密码:123
# # 欢迎回家,产口经理
# # 用户名:傻逼
# # 密码:1
# # 用户名或者密码错误
# #
# # Process finished with exit code 0
# 10
# 10
# 10
# # 24、带有验证功能的装饰器(一次登录)
# # # 解决上面例子中,需要重复登录的问题
# #
#
# user_list=[
# {'name':'alex','passwd':'123'},
# {'name':'linhaifeng','passwd':'123'},
# {'name':'wupeiqi','passwd':'123'},
# {'name':'yuanhao','passwd':'123'},
# ]
# current_dic= {"usrname":None, "login":False}
#
# def auth_func(func):
# def wrapper(*args,**kwargs):
# if current_dic["usrname"] and current_dic["login"]:
# res = func(*args, **kwargs)
# return res
# usrname = input("用户名:").strip() # 移除收尾字符的空格
# passwd = input("密码:").strip() # 移除收尾字符的空格,这里似乎不太正确,不应该家strip
# for usr_dic in user_list:
# if usrname==usr_dic["name"] and passwd==usr_dic["passwd"]:
# current_dic["usrname"] = usrname
# current_dic["login"] = passwd
# res = func(*args,**kwargs)
# return res # 如果user_list存在,直接返回,后面的else就不在运行
# else:
# print("用户名或者密码错误")
#
# return wrapper
#
# # def home():
# # pass # ???看视频
# @auth_func
# def home(*args): # 这里在调用的时候如果不给,自动打印none
# print("欢迎回家,%s"%args)
# @auth_func
# def shopping_car(name):
# print("%s的购物车里有[%s, %s, %s]"%( name,"奶茶","水瓶","苹果"))
#
# def order():
# pass
#
# def index():
# print("欢迎来到京东主页!")
#
# print('before-->',current_dic)
# index()
# print('after--->',current_dic)
# # home(current_dic["usrname"]) # 这种传值会检测不到???是 home 函数的问题
# home("产口经理")
# # shopping_car("产口经理")
#
# #
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # before--> {'usrname': None, 'login': False}
# # 欢迎来到京东主页!
# # after---> {'usrname': None, 'login': False}
# # 用户名:alex
# # 密码:123
# # 欢迎回家,产口经理
# #
# # Process finished with exit code 0
# 11
# 11
# 12
# 12
# # 25、带有参数验证功能的装饰器
#
# user_list=[
# {'name':'alex','passwd':'123'},
# {'name':'linhaifeng','passwd':'123'},
# {'name':'wupeiqi','passwd':'123'},
# {'name':'yuanhao','passwd':'123'},
# ]
# current_dic= {"usrname":None, "login":False}
# def auth(auth_type = 'filedb'):
# def auth_func(func):
# def wrapper(*args,**kwargs):
# print('认证类型是',auth_type)
# if auth_type == 'filedb':
# if current_dic["usrname"] and current_dic["login"]:
# res = func(*args, **kwargs)
# return res
# usrname = input("用户名:").strip() # 移除收尾字符的空格
# passwd = input("密码:").strip() # 移除收尾字符的空格,这里似乎不太正确,不应该家strip
# for usr_dic in user_list:
# if usrname==usr_dic["name"] and passwd==usr_dic["passwd"]:
# current_dic["usrname"] = usrname
# current_dic["login"] = passwd
# res = func(*args,**kwargs)
# return res # 如果user_list存在,直接返回,后面的else就不在运行
# else:
# print("用户名或者密码错误")
#
# elif auth_type == 'ldap':
# print("鬼才这么玩!!")
# res = func(*args, **kwargs)
# return res
# else:
# print("鬼才知道你用的什么认证方式!")
# res = func(*args, **kwargs)
# return res
#
#
# return wrapper
#
# return auth_func
#
# @auth(auth_type= 'filedb' ) # auth_func=auth(auth_type='filedb')-->@auth_func
# # 附加了一个auth_type --->index=auth_func(index)
# def index():
# print("欢迎来到京东主页!")
# @auth(auth_type= 'ldap' )
# def home(*args): # 这里在调用的时候如果不给,自动打印none
# print("欢迎回家,%s"%args)
# @auth(auth_type= 'sssss' )
# def shopping_car(name):
# print("%s的购物车里有[%s, %s, %s]"%( name,"奶茶","水瓶","苹果"))
#
#
#
#
# print('before-->',current_dic)
# index()
# print('after--->',current_dic)
# # home(current_dic["usrname"]) # 这种传值会检测不到???是 home 函数的问题
# home("产口经理")
# # shopping_car("产口经理")
#
#
# # D:Anaconda3python.exe D:/C_cache/py/day20_HanShuBiBao_ZhuangShiQi/day20_HanShuBiBao_ZhuangShiQi.py
# # before--> {'usrname': None, 'login': False}
# # 认证类型是 filedb
# # 用户名:alex
# # 密码:123
# # 欢迎来到京东主页!
# # after---> {'usrname': 'alex', 'login': '123'}
# # 认证类型是 ldap
# # 鬼才这么玩!!
# # 欢迎回家,产口经理
# #
# # Process finished with exit code 0