python进阶
day10总结
-
如何定义一个函数?
-
函数名的规范。(同变量名规范)
-
规范
-
建议
def change_num():
pass
-
-
函数的注释,说明函数的作用。
def encrypt(origin):
""" 用于数据加密和xxx """
pass -
定义函数时,参数一般有以下情况(形式参数)
-
情景1
def func(a1,a2):
pass -
情景2:
def func(a1,a2=123):
pass -
情景2:
def func(*args,**kwargs):
pass
-
-
函数的返回值,一般用于将函数执行的返回给调用者。
-
默认返回None
-
遇到return则函数执行完毕
-
练习
# 1. 生成一副扑克牌 card_color_list = ["红桃", "黑桃", "方片", "梅花"] card_nums = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] # A all_card_list = [[color, num] for color in card_color_list for num in card_nums] # 2.洗牌 random.shuffle(all_card_list) # 3.给玩家发牌 ... # 4.判断牌是:豹子?同花顺?顺子?对子?单点? calculate_same_num_rule() calculate_same_color_rule() calculate_straight_rule() ...
作业
请定义一个函数,用于计算一个字符串中字符a出现的次数并通过return返回。 参数,字符串。 返回值,字符串中 a 出现的次数。 第一题 写函数,判断用户传入的一个值(字符串或列表或元组任意)长度是否大于5,并返回真假。 # 第二题 写函数,接收两个数字参数,返回比较大的那个数字(等于时返回两个中的任意一个都可以)。 # 第三题 写函数,函数接收四个参数分别是:姓名,性别,年龄,学历,然后将这四个值通过"*"拼接起来并追加到一个student_msg.txt文件中。 第四题 补充代码,实现如下功能: 【位置1】读取文件中的每一行数据,将包含特定关键的数据筛选出来,并以列表的形式返回。 【位置1】文件不存在,则返回None 【位置2】文件不存在,输出 "文件不存在",否则循环输出匹配成功的每一行数据。 def select_content(file_path,key): # 补充代码【位置1】 result = select_content("files/xxx.txt","股票") # 补充代码【位置2】 第五题 补充代码,实现敏感词替换的功能。 def change_string(origin): # 补充代码,将字符串origin中中的敏感词替换为 **,最后将替换好的值返回。 data_list = ["苍老师","波多老师","大桥"] text = input("请输入内容:") result = change_string(text) print(result) 第六题 基于函数实现用户认证,要求: 写函数,读取的用户信息并构造为字典(用户信息存放在files/user.xlsx文件中) # 构造的字典格式如下 user_dict = { "用户名":"密码" ... } 用户输入用户名和密码,进行校验。(且密码都是密文,所以,需要将用户输入的密码进行加密,然后再与Excel中的密文密码进行比较) import hashlib def encrypt(origin): origin_bytes = origin.encode('utf-8') md5_object = hashlib.md5() md5_object.update(origin_bytes) return md5_object.hexdigest() p1 = encrypt('admin') print(p1) # "21232f297a57a5a743894a0e4a801fc3" p2 = encrypt('123123') print(p2) # "4297f44b13955235245b2497399d7a93" p3 = encrypt('123456') print(p3) # "e10adc3949ba59abbe56e057f20f883e" 扩展:密码都不是明文。 注册京东,京东存储:用户名和密码(密文) 登录京东:用户名& 密码。
day11总结
-
函数参数传递的是内存地址。
-
想重新创建一份数据再传递给参数,可以手动拷贝一份。
-
特殊:参数是动态参数时,通过*或**传参时,会将数据循环添加到参数中(类似于拷贝一份)
def fun(*args, **kwargs):
print(args, kwargs)
fun(*[11, 22, 33], **{"k1": 1, "k2": 2})
-
-
函数的返回值也是内存地址。(函数执行完毕后,其内部的所有变量都会被销毁,引用计数器为0时,数据也销毁)
def func():
name = [11,22,33]
data = name
func()def func():
name = [11,22,33]
return name
data = func()
while True:
print(data) -
当函数的参数有默认值 & 默认值是可变类型 & 函数内部会修改内部元素(有坑)
# 内部会维护一个列表 [],只要b不传值则始终使用都是这个列表。
def func(a,b=[]):
b.append(a) -
定义函数写形式参数时可以使用
*
和**
,执行函数时也可以使用。 -
函数名其实也是个变量,他也可以做列表、字典、集合等元素(可哈希)
-
函数名可以被重新赋值,也可以做另外一个函数的参数和返回值。
-
掌握 print 和 return的区别,学会分析代码的执行流程。
-
python是以函数为作用域。
-
在局部作用域中寻找某数据时,优先用自己的,自己没有就在上级作用域中寻找。
-
基于 global关键字可以在局部作用域中实现对全局作用域中的变量(全局变量)重新赋值。
如何查看一个值得内存地址? 函数的参数传递的是引用(内存地址)还是值(拷贝一份)? 看代码写结果 v1 = {} v2 = v1 v1["k1"] = 123 print(v1,v2) 看代码写结果 def func(k,v,info={}): info[k] = v return info v1 = func(1,2) print(v1) v2 = func(4,5,{}) print(v2) v3 = func(5,6) print(v3) 看代码写结果 def func(k,v,info={}): info[k] = v return info v1 = func(1,2) v2 = func(4,5,{}) v3 = func(5,6) print(v1,v2,v3) 简述第5题、第6题的结果为何结果不同。 看代码写结果 def func(*args, **kwargs): print(args, kwargs) return "完毕" v1 = func(11, 22, 33) print(v1) v2 = func([11, 22, 33]) print(v2) v3 = func(*[11, 22, 33]) print(v3) v4 = func(k1=123, k2=456) print(v4) v5 = func({"k1": 123, "k2": 456}) print(v5) v6 = func(**{"k1": 123, "k2": 456}) print(v6) v7 = func([11, 22, 33], **{"k1": 123, "k2": 456}) print(v7) v8 = func(*[11, 22, 33], **{"k1": 123, "k2": 456}) print(v8) 看代码写结果 def func(*args,**kwargs): prev = "-".join(args) data_list = [] for k,v in kwargs.items(): item = "{}-{}".format(k,v) data_list.append(item) content = "*".join(data_list) return prev,content v1 = func("北京","上海",city="深圳",count=99) print(v1) v2 = func(*["北京","上海"],**{"city":"深圳","count":99}) print(v2) 补充代码,实现获取天气信息并按照指定格式写入到文件中。 # 获取天气信息示例 import requests res = requests.get(url="http://www.weather.com.cn/data/ks/101010100.html") res.encoding = "utf-8" weather_dict = res.json() # 获取的天气信息是个字典类型,内容如下: print(weather_dict) """ { 'weatherinfo': { 'city': '北京', 'cityid': '101010100', 'temp': '18', 'WD': '东南风', 'WS': '1级', 'SD': '17%', 'WSE': '1', 'time': '17:05', 'isRadar': '1', 'Radar': 'JC_RADAR_AZ9010_JB', 'njd': '暂无实况', 'qy': '1011', 'rain': '0' } } """ import requests def write_file(**kwargs): """将天气信息拼接起来,并写入到文件 格式要求: 1. 每个城市的天气占一行 2. 每行的格式为:city-北京,cityid-101010100,temp-18... """ # 补充代码 def get_weather(code): """ 获取天气信息 """ url = "http://www.weather.com.cn/data/ks/{}.html".format(code) res = requests.get(url=url) res.encoding = "utf-8" weather_dict = res.json() return weather_dict city_list = [ {'code': "101020100", 'title': "上海"}, {'code': "101010100", 'title': "北京"}, ] # 补充代码 看代码写结果 def func(): return 1,2,3 val = func() print( type(val) == tuple ) print( type(val) == list ) 看代码写结果 def func(users,name): users.append(name) print(users) result = func(['武沛齐','李杰'],'alex') print(result) 看代码写结果 def func(v1): return v1 * 2 def bar(arg): return "%s 是什么玩意?" %(arg,) val = func('你') data = bar(val) print(data) 看代码写结果 def func(v1): return v1* 2 def bar(arg): msg = "%s 是什么玩意?" %(arg,) print(msg) val = func('你') data = bar(val) print(data) 看代码写结果 def func(): data = 2 * 2 return data data_list = [func,func,func] for item in data_list: v = item() print(v) 分析代码,写结果: def func(handler,**kwargs): extra = { "code":123, "name":"武沛齐" } kwargs.update(extra) return handler(**kwargs) def something(**kwargs): return len(kwargs) def killer(**kwargs): key_list = [] for key in kwargs.keys(): key_list.append(key) return key_list v1 = func(something,k1=123,k2=456) print(v1) v2 = func(killer,**{"name":"武沛齐","age":18}) print(v2) 两个结果输出的分别是什么?并简述其原因。 def func(): return 123 v1 = [func,func,func,func,] print(v1) v2 = [func(),func(),func(),func()] print(v2) 看代码结果 v1 = '武沛齐' def func(): print(v1) func() func() 看代码结果 v1 = '武沛齐' def func(): print(v1) func() v1 = '老男人' func() 看代码写结果 NUM_LIST = [] SIZE = 18 def f1(): NUM_LIST.append(8) SIZE = 19 def f2(): print(NUM_LIST) print(SIZE) f2() f1() f2() 看代码写结果 NUM_LIST = [] SIZE = 18 def f1(): global NUM_LIST global SIZE NUM_LIST.append(8) SIZE = 19 def f2(): print(NUM_LIST) print(SIZE) f2() f1() f2() 根据要求实现资源下载器。 启动后,让用户选择专区,每个专区用单独的函数实现,提供的专区如下: 下载 花瓣网图片专区 下载 抖音短视频专区 下载 NBA锦集 专区 在用户选择了某个功能之后,表示进入某下载专区,在里面循环提示用户可以下载的内容选项(已下载过的则不再提示下载) 提醒:可基于全部变量保存已下载过得资源。 在某个专区中,如果用户输入(Q/q)表示 退出上一级,即:选择专区。 在选择专区如果输入Q/q则退出整个程序。 每个专区实现下载的案例如下: 图片 # 可供用户下载的图片如下 image_dict = { "1":("吉他男神","https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"), "2":("漫画美女","https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"), "3":("游戏地图","https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"), "4":("alex媳妇","https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"), } # 下载图片示例 import request res = requests.get( url="https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz", headers={ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" } ) with open("alex媳妇.png",mode="wb") as f: f.write(res.content) 短视频 # 可供用户下载的短视频如下 video_dict = { "1":{"title":"东北F4模仿秀",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"}, "2":{"title":"卡特扣篮",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"}, "3":{"title":"罗斯mvp",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"}, } # 下载视频示例 import requests res = requests.get( url="https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg", headers={ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS" } ) with open('罗斯mvp.mp4', mode='wb') as f: f.write(res.content) NBA # 可供用户下载的NBA视频如下 nba_dict = { "1":{"title":"威少奇才首秀三双","url":"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"}, "2":{"title":"塔图姆三分准绝杀","url":"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"} } # 下载示例 import requests res = requests.get( url="https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0", headers={ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS" } ) with open('塔图姆三分准绝杀.mp4', mode='wb') as f: f.write(res.content) # 1.如何查看一个值得内存地址? """ 基于内置函数id来获取,例如: addr1 = id("武沛齐") addr2 = id([11,22,33,44]) """ # 2.函数的参数传递的是引用(内存地址)还是值(拷贝一份)? """ 参数参数默认传递的是引用(内存地址) """ # 3.看代码写结果 """ v1 = {} v2 = v1 v1["k1"] = 123 print(v1, v2) # {'k1': 123} {'k1': 123} """ # 4.看代码写结果 """ def func(k, v, info={}): info[k] = v return info v1 = func(1, 2) print(v1) # {1: 2} v2 = func(4, 5, {}) print(v2) # {4: 5} v3 = func(5, 6) print(v3) # {1: 2, 5: 6} """ # 5.看代码写结果 """ def func(k, v, info={}): info[k] = v return info v1 = func(1, 2) v2 = func(4, 5, {}) v3 = func(5, 6) print(v1, v2, v3) # {1: 2, 5: 6} {4: 5} {1: 2, 5: 6} """ # 6. 简述第5题、第6题的结果为何结果不同。 """ 第5题中的 v1和v3变量指向的都是函数内部维护的那个列表的内存地址。 先print(v1)时,函数内部维护的列表的值当时是{1: 2} 最后print(v3)时,函数内部维护的列表的值已被修改为{1: 2, 5: 6} 第5题中的 v1和v3变量也是指向的都是函数内部维护的那个列表的内存地址。 最后再print v1和v3 时,结果就是最终函数内部维护的列表的值,即: {1: 2, 5: 6} """ # 7.看代码写结果 """ def func(*args, **kwargs): print(args, kwargs) return "完毕" v1 = func(11, 22, 33) # (11, 22, 33) {} print(v1) # 完毕 v2 = func([11, 22, 33]) # ([11, 22, 33],) {} print(v2) # 完毕 v3 = func(*[11, 22, 33]) # (11, 22, 33) {} print(v3) # 完毕 v4 = func(k1=123, k2=456) # () {'k1': 123, 'k2': 456} print(v4) # 完毕 v5 = func({"k1": 123, "k2": 456}) # ({'k1': 123, 'k2': 456},) {} print(v5) # 完毕 v6 = func(**{"k1": 123, "k2": 456}) # () {'k1': 123, 'k2': 456} print(v6) # 完毕 v7 = func([11, 22, 33], **{"k1": 123, "k2": 456}) # ([11, 22, 33],) {'k1': 123, 'k2': 456} print(v7) # 完毕 v8 = func(*[11, 22, 33], **{"k1": 123, "k2": 456}) # (11, 22, 33) {'k1': 123, 'k2': 456} print(v8) # 完毕 """ # 8.看代码写结果 """ def func(*args, **kwargs): prev = "-".join(args) data_list = [] for k, v in kwargs.items(): item = "{}-{}".format(k, v) data_list.append(item) content = "*".join(data_list) return prev, content v1 = func("北京", "上海", city="深圳", count=99) print(v1) # ('北京-上海', 'city-深圳*count-99') v2 = func(*["北京", "上海"], **{"city": "深圳", "count": 99}) print(v2) # ('北京-上海', 'city-深圳*count-99') """ # 9.补充代码,实现获取天气信息并按照指定格式写入到文件中。【重点讲】 """ import requests def write_file(**kwargs): data_list = [] row_dict = kwargs["weatherinfo"] for k, v in row_dict.items(): group = "{}-{}".format(k, v) data_list.append(group) row_string = ",".join(data_list) with open('xxxx.txt', mode='a', encoding="utf-8") as file_object: file_object.write("{}\n".format(row_string)) def get_weather(code): url = "http://www.weather.com.cn/data/ks/{}.html".format(code) res = requests.get(url=url) res.encoding = "utf-8" weather_dict = res.json() return weather_dict city_list = [ {'code': "101020100", 'title': "上海"}, {'code': "101010100", 'title': "北京"}, ] for item in city_list: # 101020100 result_dict = get_weather(item["code"]) write_file(**result_dict) """ # 10.看代码写结果 """ def func(): return 1, 2, 3 val = func() print( type(val) == tuple) # True print( type(val) == list) # False print( type(val) == dict) # False """ """ info = { "1": [11, 22, 33], "2": {'k1': 123, "k2": 456, "k3": "999"} } index = input("请输入序号:") value = info[index] if type(value) == list: print(value[0], value[1], value[2]) elif type(value) == dict: print(value['k1'], value['k2'], value['k3']) """ # 11.看代码写结果 """ def func(users, name): users.append(name) print(users) result = func(['武沛齐', '李杰'], 'alex') # # ['武沛齐', '李杰', 'alex'] print(result) # None """ # 12.看代码写结果 """ def func(v1): return v1 * 2 def bar(arg): return "%s 是什么玩意?" % (arg,) val = func('你') data = bar(val) print(data) # 你你 是什么玩意? """ # 13.看代码写结果 """ def func(v1): return v1 * 2 def bar(arg): msg = "%s 是什么玩意?" % (arg,) print(msg) val = func('你') data = bar(val) # 你你 是什么玩意? print(data) # None """ # 14.看代码写结果 """ def func(): data = 2 * 2 return data data_list = [func,func,func] for item in data_list: v = item() print(v) # 输出: # 4 # 4 # 4 """ # 15.分析代码,写结果 """ def func(handler, **kwargs): # handler() -> killer() # kwargs = {"name": "武沛齐", "age": 18} extra = { "code": 123, "name": "武沛齐" } kwargs.update(extra) # kwargs = {"name": "武沛齐", "age": 18,"code": 123,} return handler(**kwargs) def something(**kwargs): return len(kwargs) def killer(**kwargs): # {"name": "武沛齐", "age": 18,"code": 123,} key_list = [] for key in kwargs.keys(): key_list.append(key) return key_list # ["name","age","code"] v1 = func(something, k1=123, k2=456) print(v1) # 4 v2 = func(killer, **{"name": "武沛齐", "age": 18}) print(v2) # ["name","age","code"] """ # 16.两个结果输出的分别是什么?并简述其原因。 """ def func(): return 123 v1 = [func, func, func, func, ] print(v1) # 列表,内部元素都是函数(将函数名放在列表的索引位置,函数名代指函数) v2 = [func(), func(), func(), func()] print(v2) # 列表,内部元素都是123(执行函数之后,将函数的返回值放在列表的索引位置) """ # 17.看代码结果 """ v1 = '武沛齐' def func(): print(v1) func() # 武沛齐 func() # 武沛齐 """ # 18.看代码结果 """ v1 = '武沛齐' def func(): print(v1) func() # 武沛齐 v1 = '老男人' func() # 老男人 """ # 19.看代码写结果 """ NUM_LIST = [] SIZE = 18 def f1(): NUM_LIST.append(8) SIZE = 19 def f2(): print(NUM_LIST) print(SIZE) f2() # [] 18 f1() # 无任何输出 f2() # [8] 18 """ # 20.看代码写结果 """ NUM_LIST = [11, 22, 33] SIZE = 18 def f1(): global NUM_LIST global SIZE NUM_LIST = "武沛齐" SIZE = 19 def f2(): print(NUM_LIST) print(SIZE) f2() # [11,22,33] 18 f1() # 无输出 f2() # 武沛齐 19 """ # 21.资源下载器 v1版本【重点讲】 """ import requests SELECTED_IMAGE_SET = set() # 已下载图片ID(序号) SELECTED_VIDEO_SET = set() SELECTED_NBA_SET = set() def download(file_path, url): res = requests.get( url=url, headers={ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS" } ) with open(file_path, mode='wb') as f: f.write(res.content) def download_image(): total_image_dict = { "1": ("吉他男神", "https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"), "2": ("漫画美女", "https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"), "3": ("游戏地图", "https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"), "4": ("alex媳妇", "https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"), } while True: # 构造 1.吉他男神;2.漫画美女; text_list = [] for num, item in total_image_dict.items(): if num in SELECTED_IMAGE_SET: continue data = "{}.{}".format(num, item[0]) text_list.append(data) if text_list: text = ";".join(text_list) else: text = "无可下载选项" # 输出:1.吉他男神;2.漫画美女;3.游戏地图;4.alex媳妇 print(text) # 返回上一步 index = input("请输入要选择的序号(Q/q退出):") if index.upper() == "Q": return # 选择序号 3 if index in SELECTED_IMAGE_SET: print("已下载,无法再继续下载,请重新选择!") continue group = total_image_dict.get(index) if not group: print("序号不存在,请重新选择") continue # 下载图片 file_path = "{}.png".format(group[0]) download(file_path, group[1]) # 已下载集合中 SELECTED_IMAGE_SET.add(index) def download_video(): total_video_dict = { "1": {"title": "东北F4模仿秀", 'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"}, "2": {"title": "卡特扣篮", 'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"}, "3": {"title": "罗斯mvp", 'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"}, } while True: text_list = [] for num, item in total_video_dict.items(): if num in SELECTED_VIDEO_SET: continue data = "{}.{}".format(num, item["title"]) text_list.append(data) if text_list: text = ";".join(text_list) else: text = "无可下载选项" print(text) index = input("请输入要选择的序号(Q/q退出):") if index.upper() == "Q": return if index in SELECTED_VIDEO_SET: print("已下载,无法再继续下载,请重新选择!") continue group = total_video_dict.get(index) if not group: print("序号不存在,请重新选择") continue file_path = "{}.mp4".format(group["title"]) download(file_path, group["url"]) SELECTED_VIDEO_SET.add(index) def download_nba(): total_nba_dict = { "1": {"title": "威少奇才首秀三双", "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"}, "2": {"title": "塔图姆三分准绝杀", "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"} } while True: text_list = [] for num, item in total_nba_dict.items(): if num in SELECTED_NBA_SET: continue data = "{}.{}".format(num, item["title"]) text_list.append(data) if text_list: text = ";".join(text_list) else: text = "无可下载选项" print(text) index = input("请输入要选择的序号(Q/q退出):") if index.upper() == "Q": return if index in SELECTED_NBA_SET: print("已下载,无法再继续下载,请重新选择!") continue group = total_nba_dict.get(index) if not group: print("序号不存在,请重新选择") continue file_path = "{}.mp4".format(group["title"]) download(file_path, group["url"]) SELECTED_NBA_SET.add(index) print("欢迎使用xxx系统") func_dict = { "1": download_image, "2": download_video, "3": download_nba } while True: print("1.花瓣网图片专区;2.抖音短视频专区;3.NBA锦集专区 ") choice = input("请选择序号:") if choice.upper() == "Q": break func = func_dict.get(choice) if not func: print("输入错误,请重新选择!") continue # 进入专区 func() """ # 21.资源下载器 v2版本 """ import requests DB = { "1": { "area": "花瓣网图片专区", "total_dict": { "1": ("吉他男神", "https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"), "2": ("漫画美女", "https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"), "3": ("游戏地图", "https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"), "4": ("alex媳妇", "https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"), }, "ext": "png", "selected": set() }, "2": { "area": "抖音短视频专区", "total_dict": { "1": {"title": "东北F4模仿秀", 'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"}, "2": {"title": "卡特扣篮", 'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"}, "3": {"title": "罗斯mvp", 'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"}, }, "ext": "mp4", "selected": set() }, "3": { "area": "NBA锦集专区", "total_dict": { "1": {"title": "威少奇才首秀三双", "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"}, "2": {"title": "塔图姆三分准绝杀", "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"} }, "ext": "mp4", "selected": set() }, } def download(file_path, url): res = requests.get( url=url, headers={ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS" } ) with open(file_path, mode='wb') as f: f.write(res.content) def handler(area_info): # 进入专区提醒 summary = "欢迎进入{}".format(area_info['area']) print(summary) # 专区中选择下载 while True: text_list = [] for num, item in area_info['total_dict'].items(): if num in area_info['selected']: continue if type(item) == tuple: data = "{}.{}".format(num, item[0]) else: data = "{}.{}".format(num, item["title"]) text_list.append(data) if text_list: text = ";".join(text_list) else: text = "无可下载选项" print(text) index = input("请输入要选择的序号(Q/q退出):") if index.upper() == "Q": return if index in area_info['selected']: print("已下载,无法再继续下载,请重新选择!") continue group = area_info['total_dict'].get(index) if not group: print("序号不存在,请重新选择") continue if type(group) == tuple: title, url = group else: title, url = group['title'], group['url'] file_path = "{}.{}".format(title, area_info['ext']) download(file_path, url) area_info['selected'].add(index) print("欢迎使用xxx系统") while True: print("1.花瓣网图片专区;2.抖音短视频专区;3.NBA锦集 专区 ") choice = input("请选择序号(Q/q退出):") if choice.upper() == "Q": break # 选择序号: 去db中找对应的字典信息 area_dict = DB.get(choice) if not area_dict: print("输入错误,请重新选择!") continue # 进入专区(area_dict选择的专区信息) handler(area_dict) """
View Code
day12总结
-
函数可以定义在全局、也可以定义另外一个函数中(函数的嵌套)
-
学会分析函数执行的步骤(内存中作用域的管理)
-
闭包,基于函数的嵌套,可以将数据封装到一个包中,以后再去调用。
-
装饰器
-
实现原理:基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内层函数),执行函数时再在内层函数中执行闭包中的原函数。
-
实现效果:可以在不改变原函数内部代码 和 调用方式的前提下,实现在函数执行和执行扩展功能。
-
适用场景:多个函数系统统一在 执行前后自定义一些功能。
-
装饰器示例
import functools
def auth(func):
@functools.wraps(func)
def inner(*args, **kwargs):
"""巴巴里吧"""
res = func(*args, **kwargs) # 执行原函数
return res
return inner
-
作业
请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:执行func时,先执行func函数内部代码,再输出 "after" def func(a1): return a1 + "傻叉" def base(a1,a2): return a1 + a2 + '傻缺' def foo(a1,a2,a3,a4): return a1 + a2 + a3 + a4 + '傻蛋' 请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。 import random def func(): return random.randint(1,4) result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result print(result) 请为以下函数编写一个装饰器,添加上装饰器后可以实现: 检查文件所在路径(文件件)是否存在,如果不存在自动创建文件夹(保证写入文件不报错)。 def write_user_info(path): file_obj = open(path, mode='w', encoding='utf-8') file_obj.write("武沛齐") file_obj.close() write_user_info('/usr/bin/xxx/xxx.png') 分析代码写结果: def get_data(): scores = [] def inner(val): scores.append(val) print(scores) return inner func = get_data() func(10) func(20) func(30) 看代码写结果 name = "武沛齐" def foo(): print(name) def func(): name = "root" foo() func() 看代码写结果 name = "武沛齐" def func(): name = "root" def foo(): print(name) foo() func() 看代码写结果 def func(val): def inner(a1, a2): return a1 + a2 + val return inner data_list = [] for i in range(10): data_list.append( func(i) ) print(data_list) 看代码写结果 def func(val): def inner(a1, a2): return a1 + a2 + val return inner data_list = [] for i in range(10): data_list.append(func(i)) v1 = data_list[0](11,22) v2 = data_list[2](33,11) print(v1) print(v2) # ################### 第1题 ################### """ import functools def outer(function): @functools.wraps(function) def inner(*args, **kwargs): # print("before") res = function(*args, **kwargs) # 执行原函数 print("after") return res return inner @outer def func(a1): return a1 + "傻叉" @outer def base(a1, a2): return a1 + a2 + '傻缺' @outer def foo(a1, a2, a3, a4): return a1 + a2 + a3 + a4 + '傻蛋' """ # ################### 第2题 ################### """ import random import functools def five_times(function): @functools.wraps(function) def inner(*args, **kwargs): data_list = [] for i in range(5): res = function(*args, **kwargs) # 执行原函数 data_list.append(res) return data_list return inner @five_times def func(): return random.randint(1, 4) result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result print(result) """ # ################### 第3题 ################### """ import os import functools def gard(function): @functools.wraps(function) def inner(path): # 获取路径的上级目录 # folder_path = path.rsplit('/', 1)[0] folder_path = os.path.dirname(path) # 不存在,就创建 if not os.path.exists(folder_path): os.makedirs(folder_path) res = function(path) return res return inner @gard def write_user_info(path): file_obj = open(path, mode='w', encoding='utf-8') file_obj.write("武沛齐") file_obj.close() write_user_info('/Users/wupeiqi/PycharmProjects/luffyCourse/day12/xxx.txt') """ # ################### 第4~8题 ################### # 分析过程,请参见视频讲解 def func(val): def inner(a1, a2): return a1 + a2 + val return inner data_list = [] for i in range(10): data_list.append(func(i)) # data_list 是inner函数列表 v1 = data_list[0](11, 22) # 11+22+0 v2 = data_list[2](33, 11) # 33+11+2 print(v1) print(v2)
View Code
day13总结
-
匿名函数,基于lambda表达式实现一行创建一个函数。一般用于编写简单的函数。
-
三元运算,用一行代码实现处理简单的条件判断和赋值。
-
生成器,函数中如果yield关键字
-
生成器函数
-
生成器对象
-
执行生成器函数中的代码
-
next
-
for(常用)
-
send
-
-
-
内置函数(36个)
-
推导式
-
常规操作
-
小高级操作
-
作业
看代码写结果 v = [ lambda :x for x in range(10)] print(v) print(v[0]) print(v[0]()) 看代码写结果 v = [i for i in range(10,0,-1) if i > 5] print(v) 看代码写结果 data = [lambda x:x*i for i in range(10)] print(data) print(data[0](2)) print(data[0](2) == data[8](2)) 请用列表推导式实现,踢出列表中的字符串,最终生成一个新的列表保存。 data_list = [11,22,33,"alex",455,'eirc'] new_data_list = [ ... ] # 请在[]中补充代码实现。 # 提示:可以用type判断类型 请用列表推导式实现,对data_list中的每个元素判断,如果是字符串类型,则计算长度作为元素放在新列表的元素中;如果是整型,则让其值+100 作为元素放在新的列表的元素中。 data_list = [11,22,33,"alex",455,'eirc'] new_data_list = [ ... ] # 请在[]中补充代码实现。 # 提示:可以基于三元运算实现 请使用字典推导式实现,将如果列表构造成指定格式字典. data_list = [ (1,'alex',19), (2,'老男',84), (3,'老女',73) ] # 请使用推导式将data_list构造生如下格式: """ info_dict = { 1:(1,'alex',19), 2:(2,'老男',84), 3:(3,'老女',73) } """ 有4个人玩扑克牌比大小,请对比字典中每个人的牌的大小,并输入优胜者的姓名(值大的胜利,不必考虑A)。 player = { "武沛齐":["红桃",10], "alex":["红桃",8], 'eric':["黑桃",3], 'killy':["梅花",12], } 尽量多的列举你记得的内置函数?【能记住多少就写多少,不强制去背,在此尽权利写即可,这种公共后续用的多了就自然而然就记住了】 请编写一个生成器函数实现生成n个斐波那契数列的值。 什么是斐波那契数列? 前两个数相加的结果,就是下一个数。 1 1 2 3 5 8 13 21 34 55 ... 代码结构示例,请在此基础上补充代码实现。 def fib(max_count): pass count = input("请输入要生成斐波那契数列的个数:") count = int(count) fib_generator = fib(count) for num in fib_generator: print(num) # 第1题:参考视频的分析过程(也可以自己运行比较结果是否与你分析一致) # 第2题:参考视频的分析过程(也可以自己运行比较结果是否与你分析一致) # 第3题:参考视频的分析过程(也可以自己运行比较结果是否与你分析一致) # 第4题 """ data_list = [11, 22, 33, "alex", 455, 'eirc'] new_data_list = [item for item in data_list if type(item) == int] # 请在[]中补充代码实现。 print(new_data_list) """ # 第5题 """ data_list = [11, 22, 33, "alex", 455, 'eirc'] new_data_list = [len(item) if type(item) == str else item + 100 for item in data_list] print(new_data_list) """ # 第6题 """ data_list = [ (1, 'alex', 19), (2, '老男', 84), (3, '老女', 73) ] info_dict = {item[0]: item for item in data_list} print(info_dict) """ # 第7题 """ player = { "武沛齐": ["红桃", 10], "alex": ["红桃", 8], 'eric': ["黑桃", 3], 'killy': ["梅花", 12], } winner = sorted(player.items(), key=lambda x: x[1][-1], reverse=True)[0][0] print(winner) data = sorted(player.items(), key=lambda x: x[1][1])[-1][0] print(data) """ # 第8题(自己写就好) # 第9题 def fib(max_count): first = 1 second = 0 count = 0 while count < max_count: next_value = first + second first = second second = next_value yield next_value count += 1 limit_count = input("请输入要生成斐波那契数列的个数:") limit_count = int(limit_count) fib_generator = fib(limit_count) for num in fib_generator: print(num)
View Code
day14小结
-
模块和包的区别
-
导入模块的两种方式:
import xx
from xxx import xxx -
相对导入,需要有包名称。
-
模块重名可以通过as取别名。
-
执行py文件时,内部
__name__=="__main__"
,导入模块时,被导入的模块__name__="模块名"
-
在项目开发中,一般在主文件中会写上 main (主文件标记,不是绝对的,因为其他文件在开发调试时候有时候也可能有main)。
总结
-
模块和包的区别
-
了解如何导入模块
-
路径
-
导入方式
-
-
导入模块时一般要遵循的规范【补充】
-
注释:文件顶部或init文件中。
-
在文件顶部导入
-
有规则导入,并用空行分割。
# 先内置模块
# 再第三方模块
# 最后自定义模块import os
import sys
import random
import hashlib
import requests
import openpyxl
from commons.utils import encrypt
-
-
第三方模块安装的方法
-
常见内置模块
作业:
-
自己去网上搜索如何基于Python计算mp4视频的时长,最终实现用代码统计某个文件夹下所有mp4的时长。
day15总结
-
json格式和json模块
-
json模块处理特殊的数据类型
-
datetime格式与字符串、时间戳以及相关之间的转换。
-
datetime格式时间与timedelta的加减。
-
两个datetime相减可以计算时间间隔,得到的是一个timedelta格式的时间。
-
了解正则表达式的编写方式和python中re模块的使用。
-
项目开发规范。
练习题
日志记录,将用户输入的信息写入到文件,文件名格式为年-月-日-时-分.txt。 from datetime import datetime while True: text = input("请输入内容:") if text.upper() == "Q": break current_datetime = datetime.now().strftime("%Y-%m-%d-%H-%M") file_name = "{}.txt".format(current_datetime) with open(file_name, mode='a', encoding='utf-8') as file_object: file_object.write(text) file_object.flush() 用户注册,将用户信息写入Excel,其中包含:用户名、密码、注册时间 三列。 import os import hashlib from datetime import datetime from openpyxl import load_workbook from openpyxl import workbook BASE_DIR = os.path.dirname(os.path.abspath(__file__)) FILE_NAME = "db.xlsx" def md5(origin): hash_object = hashlib.md5("sdfsdfsdfsd23sd".encode('utf-8')) hash_object.update(origin.encode('utf-8')) return hash_object.hexdigest() def register(username, password): db_file_path = os.path.join(BASE_DIR, FILE_NAME) if os.path.exists(db_file_path): wb = load_workbook(db_file_path) sheet = wb.worksheets[0] next_row_position = sheet.max_row + 1 else: wb = workbook.Workbook() sheet = wb.worksheets[0] next_row_position = 1 user = sheet.cell(next_row_position, 1) user.value = username pwd = sheet.cell(next_row_position, 2) pwd.value = md5(password) ctime = sheet.cell(next_row_position, 3) ctime.value = datetime.now().strftime("%Y-%m-%d %H:%M:%S") wb.save(db_file_path) def run(): while True: username = input("请输入用户名:") if username.upper() == "Q": break password = input("请输入密码:") register(username, password) if __name__ == '__main__': run()
View Code
作业:开发短视频资讯平台
有video.csv视频库文件,其中有999条短视频数据,格式如下:【 video.csv 文件已为大家提供好,在day15课件目录下。 】 image-20210105223331765 项目的核心功能有: 分页看新闻(每页显示10条),提示用户输入页码,根据页码显示指定页面的数据。 提示用户输入页码,根据页码显示指定页面的数据。 当用户输入的页码不存在时,默认显示第1页 搜索专区 用户输入关键字,根据关键词筛选出所有匹配成功的短视频资讯。 支持的搜索两种搜索格式: id=1715025,筛选出id等于1715025的视频(video.csv的第一列)。 key=文本,模糊搜索,筛选包含关键字的所有新闻(video.csv的第二列)。 下载专区 用户输入视频id,根据id找到对应的mp4视频下载地址,然后下载视频到项目的files目录。 视频的文件名为:视频id-年-月-日-时-分-秒.mp4 视频下载代码示例 import requests res = requests.get( url='https://video.pearvideo.com/mp4/adshort/20210105/cont-1715046-15562045_adpkg-ad_hd.mp4' ) # 视频总大小(字节) file_size = int(res.headers['Content-Length']) download_size = 0 with open('xxx.mp4', mode='wb') as file_object: # 分块读取下载的视频文件(最多一次读128字节),并逐一写入到文件中。 len(chunk)表示实际读取到每块的视频文件大小。 for chunk in res.iter_content(128): download_size += len(chunk) file_object.write(chunk) file_object.flush() message = "视频总大小为:{}字节,已下载{}字节。".format(file_size, download_size) print(message) file_object.close() res.close() 下载的过程中,输出已下载的百分比,示例代码如下: import time print("正在下载中...") for i in range(101): text = "\r{}%".format(i) print(text, end="") time.sleep(0.2) print("\n下载完成") 附赠 自动采集梨视频1000条资讯的爬虫脚本。梨视频平台系统更新后可能会导致下载失败,到时候需根据平台调整再来修改代码。 """ 下载梨视频的:视频ID,视频标题,视频URL地址 并写入到本次 video.csv 文件中。 运行此脚本需要预先安装: pip install request pip install beautifulsoup4 """ import requests from bs4 import BeautifulSoup def get_mp4_url(video_id): data = requests.get( url="https://www.pearvideo.com/videoStatus.jsp?contId={}".format(video_id), headers={ "Referer": "https://www.pearvideo.com/video_{}".format(video_id), } ) response = data.json() image_url = response['videoInfo']['video_image'] video_url = response['videoInfo']['videos']['srcUrl'] middle = image_url.rsplit('/', 1)[-1].rsplit('-', 1)[0] before, after = video_url.rsplit('/', 1) suffix = after.split('-', 1)[-1] url = "{}/{}-{}".format(before, middle, suffix) return url def download_video(): file_object = open('video.csv', mode='w', encoding='utf-8') count = 0 while count <= 999: res = requests.get( url="https://www.pearvideo.com/category_loading.jsp?reqType=14&categoryId=&start={}".format(count) ) bs = BeautifulSoup(res.text, 'lxml') a_list = bs.find_all("a", attrs={'class': "vervideo-lilink"}) for tag in a_list: title = tag.find('div', attrs={'class': "vervideo-title"}).text.strip() video_id = tag.get('href').split('_')[-1] mp4_url = get_mp4_url(video_id) row = "{},{},{}\n".format(video_id, title, mp4_url) file_object.write(row) file_object.flush() count += 1 message = "已下载{}个".format(count) print(message) file_object.close() if __name__ == '__main__': download_video()
View Code
day17总结
-
类和对象的关系。
-
面向对象编程中常见的成员:
-
绑定方法
-
实例变量
-
-
self到底是什么?
-
面向对象的三大特性。
-
面向对象的应用场景
-
数据封装。
-
封装数据 + 方法再对数据进行加工处理。
-
创建同一类的数据且同类数据可以具有相同的功能(方法)。
-
-
补充:在Python3中编写类时,默认都会继承object(即使不写也会自动继承)。
class Foo:
pass
class Foo(object):
pass这一点在Python2是不同的:
-
继承object,新式类
-
不继承object,经典类
-
作业
简述面向对象三大特性? 将以下函数改成类的方式并调用 : def func(a1): print(a1) 面向对象中的self指的是什么? 以下代码体现 向对象的什么特性? class Person(object): def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender obj = Person('武沛齐', 18, '男') 以下代码体现 向对象的 么特点? class Message(object): def email(self): """ 发送邮件 :return: """ pass def msg(self): """ 发送短信 :return: """ pass def wechat(self): """ 发送微信 :return: """ pass 看代码写结果 class Foo: def func(self): print('foo.func') obj = Foo() result = obj.func() print(result) 看代码写结果 class Base1: def f1(self): print('base1.f1') def f2(self): print('base1.f2') def f3(self): print('base1.f3') self.f1() class Base2: def f1(self): print('base2.f1') class Foo(Base1, Base2): def f0(self): print('foo.f0') self.f3() obj = Foo() obj.f0() 看代码写结果: class Base: def f1(self): print('base.f1') def f3(self): self.f1() print('base.f3') class Foo(Base): def f1(self): print('foo.f1') def f2(self): print('foo.f2') self.f3() obj = Foo() obj.f2() 补充代码实现 user_list = [] while True: user = input("请输入用户名:") pwd = input("请输入密码:") email = input("请输入邮箱:") """ # 需求 1. while循环提示 户输 : 户名、密码、邮箱(正则满足邮箱格式) 2. 为每个用户创建一个个对象,并添加到user_list中。 3. 当列表中的添加 3个对象后,跳出循环并以此循环打印所有用户的姓名和邮箱 """ 补充代码:实现 户注册和登录。 class User: def __init__(self, name, pwd): self.name = name self.pwd = pwd class Account: def __init__(self): # 用户列表,数据格式:[user对象,user对象,user对象] self.user_list = [] def login(self): """ 用户登录,输入用户名和密码然后去self.user_list中校验用户合法性 :return: """ pass def register(self): """ 用户注册,没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。 :return: """ pass def run(self): """ 主程序 :return: """ pass if __name__ == '__main__': obj = Account() obj.run() # 1. 简述面向对象三大特性? """ - 封装,将方法封装到类中 或 将数据封装到对象中,便于以后使用。 - 继承,将类中的公共的方法提取到基类中去实现。 - 多态,Python默认支持多态(这种方式称之为鸭子类型),最简单的基础下面的这段代码即可。 def func(arg): v1 = arg.copy() # 浅拷贝 print(v1) """ # 2.将以下函数改成类的方式并调用 """ class Foo(object): def func(self, a1): print(a1) obj = Foo() obj.func("武沛齐") """ # 3. 面向对象中的self指的是什么? """ self是一个参数,在通过 对象.方法 的方式去执行方法时,这个参数会被python自动传递(值为调用当前方法的对象) """ # 4.以下代码体现 向对象的什么特性? """ 封装 """ # 5. 以下代码体现 向对象的什么特性? """ 封装 """ # 6. 看代码写结果 """ foo.func None """ # 7. 看代码写结果 """ foo.f0 base1.f3 base1.f1 """ # 8. 看代码写结果 """ foo.f2 foo.f1 base.f3 """ # 9. 补充代码实现 """ import re class UserInfo(object): def __init__(self, name, pwd, email): self.name = name self.pwd = pwd self.email = email def run(): user_list = [] while True: user = input("请输入用户名:") pwd = input("请输入密码:") email = input("请输入邮箱:") match_object = re.match("(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)", email, re.ASCII) if not match_object: print("邮箱格式输入错误,请重新输入!") continue user_object = UserInfo(user, pwd, email) user_list.append(user_object) if len(user_list) == 3: break for item in user_list: print(item.name, item.email) if __name__ == '__main__': run() """ # 10. 补充代码实现 class User: def __init__(self, name, pwd): self.name = name self.pwd = pwd class Account: def __init__(self): # 用户列表,数据格式:[user对象,user对象,user对象] self.user_list = [] def login(self): """ 用户登录,输入用户名和密码然后去self.user_list中校验用户合法性 :return: """ print("用户登录") while True: user = input("请输入用户名(Q/q):") if user.upper() == 'Q': break pwd = input("请输入密码:") for user_object in self.user_list: if user == user_object.name and pwd == user_object.pwd: print("登录成功") break else: print("登录失败") def register(self): """ 用户注册,没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。 :return: """ print("用户注册") while True: user = input("请输入用户名(Q/q):") if user.upper() == 'Q': break pwd = input("请输入密码:") user_object = User(user, pwd) self.user_list.append(user_object) def run(self): """ 主程序 :return: """ method_dict = { "1": {"title": "登录", "method": self.login}, "2": {"title": "注册", "method": self.register}, } message = ";".join(["{}.{}".format(k, v['title']) for k, v in method_dict.items()]) while True: print(message) choice = input("请选择功能(Q/q):") if choice.upper() == 'Q': break info = method_dict.get(choice) if not info: print("选择错误,请重新选择") continue method = info['method'] method() # self.login() / self.register() if __name__ == '__main__': obj = Account() obj.run()
View Code
练习
class Base: def f1(self): print('base.f1') class Foo(Base): def f2(self): print('foo.f2') obj = Foo() obj.f1() obj.f2() class Base: def f1(self): print('base.f1') class Foo(Base): def f2(self): print('before') self.f1() # 调用了f1方法 obj.f1() print('foo.f2') obj = Foo() obj.f2() >>> before >>> base.f1 >>> foo.f2 class Base: def f1(self): print('base.f1') class Foo(Base): def f2(self): print("before") self.f1() # obj,Foo类创建出来的对象。 obj.f1 print('foo.f2') def f1(self): print('foo.f1') obj = Foo() obj.f1() # obj对象到底是谁?优先就会先去谁里面找。 obj.f2() >>> before >>> foo.f1 >>> foo.f2 class Base: def f1(self): print('before') self.f2() # slef是obj对象(Foo类创建的对象) obj.f2 print('base.f1') def f2(self): print('base.f2') class Foo(Base): def f2(self): print('foo.f2') obj = Foo() obj.f1() # 优先去Foo类中找f1,因为调用f1的那个对象是Foo类创建出来的。 >>> before >>> foo.f2 >>> base.f1 b1 = Base() b1.f1() >>> before >>> base.f2 >>> base.f1 class TCPServer: def f1(self): print("TCPServer") class ThreadingMixIn: def f1(self): print("ThreadingMixIn") class ThreadingTCPServer(ThreadingMixIn, TCPServer): def run(self): print('before') self.f1() print('after') obj = ThreadingTCPServer() obj.run() >>> before >>> ThreadingMixIn >>> after class BaseServer: def serve_forever(self, poll_interval=0.5): self._handle_request_noblock() def _handle_request_noblock(self): self.process_request(request, client_address) def process_request(self, request, client_address): pass class TCPServer(BaseServer): pass class ThreadingMixIn: def process_request(self, request, client_address): pass class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass obj = ThreadingTCPServer() obj.serve_forever()
View Code
day18总结
-
面向对象编程中的成员
-
变量
-
实例变量
-
类变量
-
-
-
方法 – 绑定方法 – 类方法 – 静态方法
-
属性
-
-
成员修饰符
-
对象中的数据嵌套
-
特殊成员
-
重要概念:
-
迭代器
-
生成器
-
可迭代对象
-
作业
列举面向对象的成员并简述他们的特点。 @staticmethod 和 @classmethod的作用是什么? 面向对象中如何让成员变为私有。 __new__方法的作用? 简述你理解的:迭代器、生成器、可迭代对象。 看代码写结果 class Foo(object): a1 = 1 def __init__(self,num): self.num = num def show_data(self): print(self.num+self.a1) obj1 = Foo(666) obj2 = Foo(999) print(obj1.num) print(obj1.a1) obj1.num = 18 obj1.a1 = 99 print(obj1.num) print(obj1.a1) print(obj2.a1) print(obj2.num) print(obj2.num) print(Foo.a1) print(obj1.a1) 看代码写结果,注意返回值。 class Foo(object): def f1(self): return 999 def f2(self): v = self.f1() print('f2') return v def f3(self): print('f3') return self.f2() def run(self): result = self.f3() print(result) obj = Foo() v1 = obj.run() print(v1) 看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 class Foo(object): def f1(self): print('f1') @staticmethod def f2(): print('f2') obj = Foo() obj.f1() obj.f2() Foo.f1() Foo.f2() 看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 class Foo(object): def f1(self): print('f1') self.f2() self.f3() @classmethod def f2(cls): print('f2') @staticmethod def f3(): print('f3') obj = Foo() obj.f1() 看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 class Base(object): @classmethod def f2(cls): print('f2') @staticmethod def f3(): print('f3') class Foo(Base): def f1(self): print('f1') self.f2() self.f3() obj = Foo() obj.f1() 看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 class Foo(object): a1 = 1 __a2 = 2 def __init__(self,num): self.num = num self.__salary = 1000 def show_data(self): print(self.num+self.a1) obj = Foo(666) print(obj.num) print(obj.a1) print(obj.__salary) print(obj.__a2) print(Foo.a1) print(Foo.__a2) obj.show_data() 看代码写结果 class Foo(object): def __init__(self, age): self.age = age def display(self): print(self.age) data_list = [Foo(8), Foo(9)] # print(data_list[0].age) # data_list[1].display() for item in data_list: print(item.age, item.display()) 看代码写结果 class Base(object): def __init__(self, a1): self.a1 = a1 def f2(self, arg): print(self.a1, arg) class Foo(Base): def f2(self, arg): print('666') obj_list = [Base(1), Foo(2), Foo(3)] for item in obj_list: item.f2(1) 看代码写结果 class Foo(object): def __init__(self, num): self.num = num v1 = [Foo for i in range(10)] v2 = [Foo(5) for i in range(10)] v3 = [Foo(i) for i in range(10)] print(v1) print(v2) print(v3) 看代码写结果 class StarkConfig(object): def __init__(self, num): self.num = num def changelist(self, request): print(self.num, request) config_obj_list = [ StarkConfig(1), StarkConfig(2), StarkConfig(3) ] for item in config_obj_list: print(item.num) 看代码写结果 class StarkConfig(object): def __init__(self, num): self.num = num def changelist(self, request): print(self.num, request) config_obj_list = [StarkConfig(1), StarkConfig(2), StarkConfig(3)] for item in config_obj_list: item.changelist(666) 看代码写结果 class StarkConfig(object): def __init__(self, num): self.num = num def changelist(self, request): print(self.num, request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self, request): print(666, self.num) class AdminSite(object): def __init__(self): self._registry = {} def register(self, k, v): self._registry[k] = v site = AdminSite() site.register('武沛齐', StarkConfig(19)) site.register('root', StarkConfig(20)) site.register("admin", RoleConfig(33)) print(len(site._registry)) for k, row in site._registry.items(): row.changelist(5) 看代码写结果(如有报错,请标注报错位置) class StarkConfig(object): def __init__(self, num): self.num = num def run(self): self() def __call__(self, *args, **kwargs): print(self.num) class RoleConfig(StarkConfig): def __call__(self, *args, **kwargs): print(345) def __getitem__(self, item): return self.num[item] v1 = RoleConfig('alex') v2 = StarkConfig("wupeiqi") print(v1[1]) print(v2[2]) 补全代码 class Context: pass with Context() as ctx: ctx.do_something() 看代码写结果 class Department(object): def __init__(self,title): self.title = title class Person(object): def __init__(self,name,age,depart): self.name = name self.age = age self.depart = depart def message(self): msg = "我是%s,年龄%s,属于%s" %(self.name,self.age,self.depart.title) print(msg) d1 = Department('人事部') d2 = Department('销售部') p1 = Person('武沛齐',18,d1) p2 = Person('alex',18,d1) p1.message() p2.message() 分析代码关系,并写出正确的输出结果。 class Node(object): def __init__(self, title): self.title = title self.children = [] def add(self, node): self.children.append(node) def __getitem__(self, item): return self.children[item] root = Node("中国") root.add(Node("河南省")) root.add(Node("河北省")) print(root.title) print(root[0]) print(root[0].title) print(root[1]) print(root[1].title) 分析代码关系,并写出正确的输出结果。 class Node(object): def __init__(self, title): self.title = title self.children = [] def add(self, node): self.children.append(node) def __getitem__(self, item): return self.children[item] root = Node("中国") root.add(Node("河南省")) root.add(Node("河北省")) root.add(Node("陕西省")) root.add(Node("山东省")) root[1].add(Node("石家庄")) root[1].add(Node("保定")) root[1].add(Node("廊坊")) root[3].add(Node("潍坊")) root[3].add(Node("烟台")) root[3].add(Node("威海")) root[1][1].add(Node("雄安")) root[1][1].add(Node("望都")) print(root.title) print(root[0].title) print(root[1].title) print(root[1][0].title) print(root[1][2].title) print(root[1][1][0].title) # 1. 列举面向对象的成员并简述他们的特点。 """ - 变量 - 实例变量,属于对象。每个对象中中都封装各自的值。只能通过的对象来进行调用。 - 类变量,属于类。每个类中各自保存的数据。可以通过对象和类来进行读取。 - 方法 - 绑定方法,默认有一个self参数,由对象进行调用(此时self就等于调用方法的这个对象)【对象&类均可调用】 - 类方法,默认有一个cls参数,用类或对象都可以调用(此时cls就等于调用方法的这个类)【对象&类均可调用】 - 静态方法,无默认参数,用类和对象都可以调用。【对象&类均可调用】 - 属性 基于方法+property装饰器实现可以实现,可以实现 obj.属性名 obj.属性名 = 123 del obj.属性名 语法和方法的对应关系。 """ # 2. @staticmethod 和 @classmethod的作用是什么? """ @classmethod,将一个方法变换类方法;类和方法都可以调用,且cls默认是当前执行该方法的类。 @staticmethod,将一个方法变换为静态方法,静态方法的调用可以是类也可以对象,无默认参数。 """ # 3. 面向对象中如何让成员变为私有。 """ 前面加上 __ """ # 4. `__new__`方法的作用? """ __new__是构造方法,用于创建对象(空对象),在__init__方法执行之前。 """ # 5. 简述你理解的:迭代器、生成器、可迭代对象。 """ 迭代器,含有__iter__方法和__next__方法,__iter__返回自身,__next__可以获取数据(终止是抛出StopIteration异常。可以被for循环。 生成器,在定义时是函数中重要包含yield就是生成器函数,执行函数获得生成器对象(一种特殊的迭代器);可以通过next取值 & 也可以通过for循环取值。 可迭代对象,含有 __iter__方法,且返回一个迭代器对象。可以被for循环。 """ # 6. 看代码写结果 """ 666 1 18 99 1 999 999 1 99 """ # 7. 看代码写结果,注意返回值。 """ f3 f2 999 None """ # 8. 看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 """ class Foo(object): def f1(self): print('f1') @staticmethod def f2(): print('f2') obj = Foo() obj.f1() # f1 obj.f2() # f2 Foo.f1() # 报错 Foo.f2() # f2 """ # 9.看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 """ f1 f2 f3 """ # 10.看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 """ f1 f2 f3 """ # 11.看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】 """ class Foo(object): a1 = 1 __a2 = 2 def __init__(self, num): self.num = num self.__salary = 1000 def show_data(self): print(self.num + self.a1) obj = Foo(666) print(obj.num) # 666 print(obj.a1) # 1 print(obj.__salary) # 报错 print(obj.__a2) # 报错 print(Foo.a1) # 1 print(Foo.__a2) # 报错 obj.show_data() # 667 """ # 12.看代码写结果 """ 8 8 None 9 9 None """ # 13.看代码写结果 """ 1 1 666 666 """ # 14.看代码写结果 """ class Foo(object): def __init__(self, num): self.num = num v1 = [Foo for i in range(10)] v2 = [Foo(5) for i in range(10)] v3 = [Foo(i) for i in range(10)] print(v1) # [类,类,类...] print(v2) # [对象(num=5),对象(num=5),对象(num=5)..] print(v3) # [对象(num=0),对象(num=1),对象(num=2)..] """ # 15.看代码写结果 """ 1 2 3 """ # 16.看代码写结果 """ 1 666 2 666 3 666 """ # 17. 看代码写结果 """ 3 19 5 20 5 666 33 """ # 18. 看代码写结果 """ class StarkConfig(object): def __init__(self, num): self.num = num def run(self): self() def __call__(self, *args, **kwargs): print(self.num) class RoleConfig(StarkConfig): def __call__(self, *args, **kwargs): print(345) def __getitem__(self, item): return self.num[item] v1 = RoleConfig('alex') v2 = StarkConfig("wupeiqi") print(v1[1]) # l print(v2[2]) # 报错 """ # 19.补全代码 """ class Context: def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): pass def do_something(self): pass with Context() as ctx: ctx.do_something() """ # 20.看代码写结果 """ 我是武沛齐,年龄18,属于人事部 我是alex,年龄18,属于人事部 """ # 21.分析代码关系,并写出正确的输出结果。 """ 中国 Node对象(title=河南省) 河南省 Node对象(title=河北省) 河北省 """ # 22. 分析代码关系,并写出正确的输出结果。 """ 中国 河南省 河北省 石家庄 廊坊 雄安 """
View Code
面试题
class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print(Parent.x, Child1.x, Child2.x) # 1 1 1 Child1.x = 2 # 在 Child类中新增实例变量x=2 print(Parent.x, Child1.x, Child2.x) # 1 2 1 Parent.x = 3 print(Parent.x, Child1.x, Child2.x) # 3 2 3
View Code
day19总结
-
了解 mro和c3算法
-
python2和python3在面向对象中的区别。
-
内置函数
staticmethod,classmethod,property,callable,type,isinstance,issubclass,super
getattr,setattr,hasattr,delattr -
异常处理
-
根据字符串的形式导入模块
import_module
-
根据字符串的形式操作成员
反射-getattr,setattr,hasattr,delattr
作业
-
super的作用?
-
看图分析类A的继承关系
看代码写结果 class Foo(object): def __init__(self, name, age): self.name = name self.age = age @property def message(self): return "{}-{}".format(self.name, self.age) class Bar(Foo): def __init__(self, email, *args, **kwargs): super().__init__(*args, **kwargs) self.email = email def total(self): data = "{}-{}-{}".format(self.name, self.age, self.email) return data obj1 = Foo("武沛齐", 20) print(obj1.message) obj2 = Bar("xx@live.com", "root", 100) print(obj2.message) obj2.total() 看代码写结果 class Foo(object): def __call__(self, *args, **kwargs): return 666 data_list = [ "武沛齐", dict, lambda :123, True, Foo, Foo() ] for item in data_list: if callable(item): val = item() print(val) else: print(item) 如何主动触发一个异常? 反射的作用? 看代码写结果 class Person(object): title = "北京" def __init__(self, name, wx): self.name = name self.wx = wx def show(self): message = "姓名{},微信:{}".format(self.name, self.wx) return message @property def message(self): return 666 @staticmethod def something(): return 999 obj = Person("武沛齐", "wupeiqi666") print(getattr(obj, 'wx')) print(getattr(obj, 'message')) print(getattr(obj, 'show')()) print(getattr(obj, 'something')()) # 1.super的作用 """ 根据类继承关系向上寻找成员 """ # 2. 类继承关系 """ A,B,C,M,D,F,J,G,H """ # 3.看代码写结果 """ 武沛齐-20 root-100 """ # 4.看代码写结果 """ 武沛齐 {} 或 空字典 123 True Foo类的对象 666 """ # 5.如何主动触发一个异常? """ raise 异常类(...) """ # 6.反射的作用? """ 以字符串的形式去对象中操作成员 """ # 7. 看代码写结果 """ wupeiqi666 666 姓名武沛齐,微信:wupeiqi666 999 """
View Code
day20总结
-
了解常见设备和网络架构。
-
掌握常见网络词汇的意思。
-
了解B/S和C/S架构的区别。
-
基于Python的socket模块实现网络编程。
作业
-
简述 二层交换机 & 路由器 & 三层交换机 的作用。
-
简述常见词:IP、子网掩码、DHCP、公网IP、端口、域名的作用。
-
实现远程用户认证系统。
客户端:
1. 运行程序,连接服务端并获取服务端发送的欢迎使用xx系统信息。
2. 输入用户名和密码,并将用户名和密码发送到服务端去校验。
3. 登录失败,重试(Q退出)。
4. 登录成功,进入系统,提示登录成功
服务端:
1. 客户端连接上服务端,返回 欢迎使用xx系统信息。
2. 等待客户端发送用户名和密码进行校验(用户名和密码在文件中)
3. 登录失败,返回错误信息。
4. 登录成功,返回成功提示的内容。
client.py import socket import json # 1. 向指定IP发送连接请求 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('127.0.0.1', 8001)) # 2.连接成功后,获取系统登录信息 message = client.recv(1024) print(message.decode("utf-8")) while True: user = input("请输入用户名:") pwd = input("请输入密码:") content = "{}|{}".format(user, pwd) client.sendall(content.encode("utf-8")) reply = client.recv(1024) info = json.loads(reply.decode("utf-8")) if info['status']: print(info['msg']) # 登录成功 break else: print(info['msg']) # 登录失败 # 关闭连接 client.close() sever.py import socket import json # 1.监听本机的IP和端口 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('127.0.0.1', 8001)) # 127.0.0.1 或 查看自己局域网本地IP地址 sock.listen(5) while True: # 2.等待,有人来连接(阻塞) conn, addr = sock.accept() # 3.连接成功后立即发送 conn.sendall("欢迎使用xx系统".encode("utf-8")) while True: # 3.等待接受信息 data = conn.recv(1024) if not data: break data_string = data.decode("utf-8") username, password = data_string.split('|') file_object = open("db.csv", mode='r', encoding='utf-8') is_success = False for line in file_object: user, pwd = line.strip().split(",") if user == username and pwd == password: is_success = True file_object.close() if is_success: info = {"status": True, 'msg': "登录成功"} conn.sendall(json.dumps(info).encode("utf-8")) break else: info = {"status": False, 'msg': "登录失败"} conn.sendall(json.dumps(info).encode("utf-8")) # 5.关闭与此人的连接 conn.close() # 6.停止服务端程序 sock.close()
View Code
day21总结
-
OSI 7层模型
应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
-
UDP和TCP的区别
UDP,速度快但无法保证数据的准确性。
TCP,需要先创建可靠连接,在进行收发数据(ack)。 -
TCP的三次握手和四次挥手
-
为什么会有粘包?如何解决?
-
如何让socket请求变成非阻塞?
-
IO多路复用的作用?
监测多个 IO对象 是否发生变化(可读/可写)。
-
IO多路复用 + 非阻塞 + socket服务端,可以让服务端同时处理多个客户端的请求。
-
IO多路复用 + 非阻塞 + socket客户端,可以向服务端同时发起多个请求。
作业(模块大作业)
请基于TCP协议实现一个网盘系统,包含客户端、服务端,各自需求如下:
-
客户端
-
用户注册,注册成功之后,在服务端的指定目录下为此用户创建一个文件夹,该文件夹下以后存储当前用户的数据(类似于网盘)。
-
用户登录
-
查看网盘目录下的所有文件(一级即可),ls命令
-
上传文件,如果网盘已存在则重新上传(覆盖)。
-
下载文件(进度条)
先判断要下载本地路径中是否存在该文件。
- 不存在,直接下载
- 存在,则让用户选择是否续传(继续下载)。
- 续传,在上次的基础上继续下载。
- 不续传,从头开始下载。
-
-
服务端
-
支持注册,并为用户初始化相关目录。
注册成功之后,将所有用户信息存储到特定的Excel文件中
-
支持登录
-
支持查看当前用户网盘目录下的所有文件。
-
支持上传
-
支持下载
-
day22总结
-
进程和线程的区别和应用场景。
-
什么是GIL锁
-
多线程和线程池的使用。
-
线程安全 & 线程锁 & 死锁
-
单例模式
作业
简述进程和线程的区别以及应用场景。 什么是GIL锁 手写单例模式 程序从flag a执行到falg b的时间大致是多少秒? import threading import time def _wait(): time.sleep(60) # flag a t = threading.Thread(target=_wait) t.setDaemon(False) t.start() # flag b 程序从flag a执行到falg b的时间大致是多少秒? import threading import time def _wait(): time.sleep(60) # flag a t = threading.Thread(target=_wait) t.setDaemon(True) t.start() # flag b 程序从flag a执行到falg b的时间大致是多少秒? import threading import time def _wait(): time.sleep(60) # flag a t = threading.Thread(target=_wait) t.start() t.join() # flag b 读程序,请确认执行到最后number是否一定为0 import threading loop = int(1E7) def _add(loop = 1): global number for _ in range(loop): number += 1 def _sub(loop = 1): global number for _ in range(loop): number -= 1 number = 0 ta = threading.Thread(target=_add,args=(loop,)) ts = threading.Thread(target=_sub,args=(loop,)) ta.start() ta.join() ts.start() ts.join() 读程序,请确认执行到最后number是否一定为0 import threading loop = int(1E7) number = 0 def _add(loop = 1): global number for _ in range(loop): number += 1 def _sub(loop = 1): global number for _ in range(loop): number -= 1 ta = threading.Thread(target=_add,args=(loop,)) ts = threading.Thread(target=_sub,args=(loop,)) ta.start() ts.start() ta.join() ts.join() data.txt 文件中共有 10000 条数据,请为每 100行 数据创建一个线程,并在线程中把当前100条数据的num列相加并打印。 subscription_id,erotic,num ASDFOKASDJF423KASDFJASDF,5,1 FSD23R23SFSDF4DFGDFGDFGDF,5,99 ASDDSFGWERTCERT44GFGDSFG,5,2 FFFFFFSDSVFG5RTFGDDFFFFA,5,11 ASDFASDF3234XCVWEGDFGSAF,5,1 ... # 1.简述进程和线程的区别以及应用场景。 """ 线程,是计算机中可以被cpu调度的最小单元(真正在工作)。 进程,是计算机资源分配的最小单元(进程为线程提供资源)。 一个进程中可以有多个线程,同一个进程中的线程可以共享此进程中的资源。 由于GIL锁的存在,控制一个进程中同一时刻只有一个线程可以被CPU调度。所以 - 计算密集型,适合用多进程开发。 - IO密集型,适合用多线程开发。 """ # 2.什么是GIL锁 """ GIL是Cpython解释器特有的一个全局解释器锁,控制一个进程中同一时刻只有一个线程可以被CPU调度。 同时像列表、字典等常见对象的线程数据安全,也得益于GIL。 """ # 3.单例模式 """ import threading class Singleton: instance = None lock = threading.RLock() def __new__(cls, *args, **kwargs): if cls.instance: return cls.instance with cls.lock: if cls.instance: return cls.instance time.sleep(0.1) cls.instance = object.__new__(cls) return cls.instance """ # 4.程序从flag a执行到falg b的时间大致是多少秒? """ 60 """ # 5.程序从flag a执行到falg b的时间大致是多少秒? """ 0 """ # 6.程序从flag a执行到falg b的时间大致是多少秒? """ 60 """ # 7.读程序,请确认执行到最后number是否一定为0 """ 结果为0 """ # 8.读程序,请确认执行到最后number是否一定为0 """ 结果不一定为0 """ # 9.data.txt 文件中共有 10000 条数据,请为每 100行 数据创建一个线程,并在线程中把当前100条数据的num列相加并打印。 """ import threading def task(row_list): num_list = [int(row.split(",")[-1]) for row in row_list] result = sum(num_list) print(result) def run(): file_object = open('data.txt', mode='r', encoding='utf-8') file_object.readline() row_list = [] for line in file_object: row_list.append(line.strip()) if len(row_list) == 100: t = threading.Thread(target=task, args=(row_list,)) t.start() row_list = [] # 千万不要用 row_list.clear() if row_list: t = threading.Thread(target=task, args=(row_list,)) t.start() file_object.close() if __name__ == '__main__': run() """
View Code
day23总结
-
了解的进程的几种模式
-
掌握进程和进程池的常见操作(以后公司写一些脚本 爬虫会用到进程池 , 项目中框架里会有现成的)
-
进程之间数据共享
-
进程锁
-
协程、进程、线程的区别(概念)
请定义一个函数,用于计算一个字符串中字符a出现的次数并通过return返回。 参数,字符串。 返回值,字符串中 a 出现的次数。 第一题 """ def char_count(text): count = 0 for char in text: if char == 'a': count += 1 return count result = char_count("89alskdjf;auqkaaafasdfiojqln") """ 写函数,判断用户传入的一个值(字符串或列表或元组任意)长度是否大于5,并返回真假。 # 第二题 """ def judge_length(data): if len(data) > 5: return True return False result = judge_length("武沛齐武沛齐") print(result) """ 写函数,接收两个数字参数,返回比较大的那个数字(等于时返回两个中的任意一个都可以)。 # 第三题 """ def get_bigger(num1, num2): if num1 > num2: return num1 return num2 result = get_bigger(11, 22) """ 写函数,函数接收四个参数分别是:姓名,性别,年龄,学历,然后将这四个值通过"*"拼接起来并追加到一个student_msg.txt文件中。 第四题 """ def write_file(name, gender, age, degree): data_list = [name, gender, age, degree] data = "*".join(data_list) with open('student_msg.txt', mode='a', encoding='utf-8') as file_object: file_object.write(data) write_file("武沛齐", "男", "18", "博士") """ 补充代码,实现如下功能: 【位置1】读取文件中的每一行数据,将包含特定关键的数据筛选出来,并以列表的形式返回。 【位置1】文件不存在,则返回None 【位置2】文件不存在,输出 "文件不存在",否则循环输出匹配成功的每一行数据。 def select_content(file_path,key): # 补充代码【位置1】 result = select_content("files/xxx.txt","股票") # 补充代码【位置2】 第五题 """ import os def select_content(file_path, key): # 补充代码【位置1】 if not os.path.exists(file_path): return data_list = [] with open(file_path, mode='r', encoding='utf-8') as file_object: for line in file_object: if key in line: data_list.append(line) return data_list result = select_content("files/xxx.txt", "股票") if result == None: print("文件不存在") else: print(result) """ 补充代码,实现敏感词替换的功能。 def change_string(origin): # 补充代码,将字符串origin中中的敏感词替换为 **,最后将替换好的值返回。 data_list = ["苍老师","波多老师","大桥"] text = input("请输入内容:") result = change_string(text) print(result) 第六题 """ def change_string(origin): # 补充代码,将字符串origin中中的敏感词替换为 **,最后将替换好的值返回。 data_list = ["苍老师", "波多老师", "大桥"] for item in data_list: origin = origin.replace(item, "**") return origin text = input("请输入内容:") result = change_string(text) print(result) """ 基于函数实现用户认证,要求: 写函数,读取的用户信息并构造为字典(用户信息存放在files/user.xlsx文件中) # 构造的字典格式如下 user_dict = { "用户名":"密码" ... } 用户输入用户名和密码,进行校验。(且密码都是密文,所以,需要将用户输入的密码进行加密,然后再与Excel中的密文密码进行比较) import hashlib def encrypt(origin): origin_bytes = origin.encode('utf-8') md5_object = hashlib.md5() md5_object.update(origin_bytes) return md5_object.hexdigest() p1 = encrypt('admin') print(p1) # "21232f297a57a5a743894a0e4a801fc3" p2 = encrypt('123123') print(p2) # "4297f44b13955235245b2497399d7a93" p3 = encrypt('123456') print(p3) # "e10adc3949ba59abbe56e057f20f883e" 扩展:密码都不是明文。 注册京东,京东存储:用户名和密码(密文) 登录京东:用户名& 密码。 # 第七题 """ import hashlib from openpyxl import load_workbook def get_user_dict(): user_dict = {} wb = load_workbook("files/user.xlsx") sheet = wb.worksheets[0] for row in sheet.rows: user_dict[row[1].value] = row[2].value return user_dict def encrypt(origin): origin_bytes = origin.encode('utf-8') md5_object = hashlib.md5() md5_object.update(origin_bytes) return md5_object.hexdigest() user = input("请输入用户名:") pwd = input("请输入密码:") encrypt_password = encrypt(pwd) user_dict = get_user_dict() db_password = user_dict.get(user) if encrypt_password == db_password: print("登录成功") else: print("登录失败") """