python学习07-7月7日
02正则表达式
03爬虫练习
04hashlib
05configparser
06logging
09序列化模块
10模块和包
#复习
import queue q = queue.Queue() q.put(1) print(q) from collections import deque dq = deque() dq.append(1) dq.insert(0,2) # 处理速度较列表快速 print(dq) print(dq[1]) #插入比较:deque > 10*list # ['a','b','c','d','e'] # --> 'b' 'c' 之间插入一个'f' ,'d','e'也会移动 # 链表 # 【内容,next指针】 # ['a'->'b'->'c'->'d'->'e'] #断开 b和c b->f f->c #取值 d[i]: list > deque #道理同上 #正则表达式 # 元字符 . \w \d \s \W \D \S ^ $ [] [^] () | # 量词 ?+ * {n} {n.} {n.m} # 贪婪匹配 量词? 惰性 import random def rm(m,n): m = m*100 y = 0 l = [] for i in range(n): print(m) d = random.randint(1,m-1) y = m - d m = y if(i!=n):l.append(d) if(i==n-1): print('yyy',y) l.append(y) print(l,sum(l)) return random.sample(l,n) print(rm(100,9))
02正则表达式
# -*- coding:utf-8 -*- #贪婪匹配 #贪婪 后向前匹配 #非 向后匹配 每次判断 # . 是任意字符 # * 是取 0 至 无限长度 # ? 是非贪婪模式。 # 何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在: # .*?x # # 就是取前面任意长度的字符,直到一个x出现 import re ret= re.match('\d','2b22abcd') print(ret.group()) # 匹配正则开头的 #检查 string 的 开头 是否 有 字符 与 pattern 匹配。 #match( pattern, string [, flags]) #findall: 取所有,返回列表 #search: 取匹配第一个 返回对象 #match : 取以开始的第一个 返回对象 ret = re.split(',','a,b,c,d') print(ret) ret = re.split('\d','a1b23c3d4e5f') print(ret) ret = re.split('\d+','a1b23c3d4e5f') print(ret) ret = re.split('\||,| ','a|b,c,d f') print(ret) ret = re.sub('\d+','|','a1b23c3d4e5f') print(ret) ret = re.subn('\d+','|','a1b23c3d4e5f') print(ret) re.search('\d\*\d','1+2-3+4-30') #\d\*\d 先编再进行匹配 --> 翻译成python解析器可识别的 #在进行匹配 #第一步:编译对象 obj = re.compile('\d{3}') #第二部:执行方法 print(obj.search('abcd123eeee')) print(obj.findall('abcd123eeee')) #返回一个可迭代对象 ret = re.finditer('\d','a1b2c3d4') print(ret) print(next(ret)) for i in ret: print(i.group()) # findall # search # match # split # sub/subn # compile # finditer #() 的优先显示 ret = re.findall('www\.(.+)\.com','www.baidu.com') print(ret) #保留你分隔的值 ret = re.split('(\d+)','e1a3a4y') print(ret) #1、匹配标签 ret = re.search('<(\w+)>\w+</(\w+)>','<h1>hello</h1>') print(ret.group(1)) print(ret.group(2)) #h1 != b1 也能匹配 ret = re.search('<(\w+)>\w+</(\w+)>','<h1>hello</b1>') print(ret.group(1)) print(ret.group(2)) #增加分组 ret = re.search('<(?P<tag>\w+)>\w+</(?P=tag)>','<h1>hello</b1>') #print(ret.group('tag_name')) ret = re.search('<(?P<tag>\w+)>\w+</(?P=tag)>','<h1>hello</h1>') print('tag_name',ret.group('tag')) #使用编号分组 \n ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>") #如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致 #获取的匹配结果可以直接用group(序号)拿到对应的值 print(ret.group(1)) print(ret.group()) # #2、匹配整数 ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))") print(ret) #['1', '2', '60', '40', '35', '5', '4', '3'] # 结果错误 #需要现将 小数去掉 ret=re.findall("\d+(?:\.\d+)?","1-2*(60+(-40.35/5)-(-4*3))") #取消分组法 print(ret) ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))") #()优先显示,去掉空 print(ret) #['1', '-2', '60', '', '5', '-4', '3'] ret.remove("") #4、爬虫练习 # flages 选择 # re.I(IGNORECASE)忽略大小写,括号内是完整的写法 # re.M(MULTILINE)多行模式,改变^和$的行为 # re.S(DOTALL)点可以匹配任意字符,包括换行符 # re.L(LOCALE)做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用 # re.U(UNICODE) 使用\w \W \s \S \d \D使用取决于unicode定义的字符属性。在python3中默认使用该flag # re.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释 #正则指引
03爬虫练习
# -*- coding:utf-8 -*- import re from urllib.request import urlopen import ssl def get_page(url): context = ssl._create_unverified_context() response = urlopen(url,context=context) return response.read().decode('utf-8') def parse_page(s): rt ='<em class="">(?P<id>\d+)</em>.*?' \ '<span class="title">(?P<title>\w+)</span>.*?' \ '<span class="rating_num" property="v:average">(?P<rating_num>.*?)</span>.*?' \ '<span>(?P<comment_num>\d+)人评价</span>' com = re.compile(rt,flags=re.S) ret = com.finditer(s) for i in ret: #print(i.group('id'),i.group('title'),i.group('rating_num'),i.group('comment_num')) yield { "id": i.group("id"), "title": i.group("title"), "rating_num": i.group("rating_num"), "comment_num": i.group("comment_num"), } def main(num): url='https://movie.douban.com/top250?start=%s&filter='%num response_html=get_page(url) ret = parse_page(response_html) print(ret) f = open("move_info7.txt", "a", encoding="utf8") for obj in ret: print(obj) data = str(obj) f.write(data + "\n") if __name__ == '__main__': count=0 for i in range(10): main(count) count+=25
04hashlib
# -*- coding:utf-8 -*- # import hashlib hashlib.md5() #32位16进制的字符串 hashlib.sha1() #32位32进制的字符串 hashlib.sha256() hashlib.sha3_512() s = 'abcd1234' md5_obj = hashlib.md5() md5_obj.update(s.encode('utf-8')) p = md5_obj.hexdigest() print(p) s = 'abcd1234' username = 'username' md5_obj = hashlib.md5(username.encode('utf-8')) md5_obj.update(s.encode('utf-8')) p = md5_obj.hexdigest() print(p) # 1)使用同一个算法 同一个字符串 结果是一样的 # 2)摘要工程不可逆 # 3)对于不同的计算结果总是不同的 #md5sum 校验文件一致性 # 登录秘文 # 校验文件一致性 def compare(): with open(r'02正则表达式.py','rb') as f1,\ open(r'02正则表达式_1.py','rb') as f2: c1 = f1.read() c2 = f2.read() md1 = hashlib.md5() md1.update(c1) md2 = hashlib.md5() md2.update(c2) return md1.hexdigest() == md2.hexdigest() print(compare()) s = 'abc' s1 = 'd1' s2 = '234' md5_obj = hashlib.md5() md5_obj.update(s.encode('utf-8')) md5_obj.update(s1.encode('utf-8')) md5_obj.update(s2.encode('utf-8')) p = md5_obj.hexdigest() print(p) #与abcd1234 结果一致 import os def get_md5(file,n=10240): with open(file,'rb') as f1: md = hashlib.md5() fz = os.path.getsize(file) while fz>0: md.update(f1.read(n)) fz -= n return md.hexdigest() def compare1(file1,file2): return get_md5(file1)==get_md5(file2) print(compare1('02正则表达式_1.py','02正则表达式.py'))
05configparser
# -*- coding:utf-8 -*- # [组名 section] # key = value import configparser # key 将不区分大小写 config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9', 'ForwardX11':'yes', 'file_path':r'aaa.py' } config['bitbucket.org'] = {'User':'hg'} config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} with open('config.ini', 'w') as configfile: config.write(configfile) import configparser config = configparser.ConfigParser() #---------------------------查找文件内容,基于字典的形式 print(config.sections()) # [] config.read('config.ini') print(config.sections()) # 不显示DEFAULT ['bitbucket.org', 'topsecret.server.com'] print('bytebong.com' in config) # False print('bitbucket.org' in config) # True print(config['bitbucket.org']["user"]) # hg print(config['DEFAULT']['Compression']) #yes print(config['topsecret.server.com']['ForwardX11']) #no print(config['bitbucket.org']) #<Section: bitbucket.org> for key in config['bitbucket.org']: # 注意,有default会默认default的键 print(key) #局部组将打印有default全局组 print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键 print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对 print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value #增删改操作 import configparser config = configparser.ConfigParser() config.read('example.ini') config.add_section('yuan') config.remove_section('bitbucket.org') config.remove_option('topsecret.server.com',"forwardx11") config.set('topsecret.server.com','k1','11111') config.set('yuan','k2','22222') config.write(open('new2.ini', "w"))
06logging
# -*- coding:utf-8 -*- #1、简单配置方式 1)中文乱码 2)不能同时屏幕和文件输出 #2、logger对象配置方式 # import logging # logging.debug('debug message') # 调试模式 # logging.info('info message') # 基础正常信息 # logging.warning('warning message') # 警告信息 # logging.error('error message') # 错误信息 # logging.critical('critical message') #危险的 import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='test.log', filemode='a') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') #默认不打印debug 和info # logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: # # filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 # filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。 # format:指定handler使用的日志显示格式。 # datefmt:指定日期时间格式。 # level:设置rootlogger(后边会讲解具体概念)的日志级别 # stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 # # format参数中可能用到的格式化串: # %(name)s Logger的名字 # %(levelno)s 数字形式的日志级别 # %(levelname)s 文本形式的日志级别 # %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 # %(filename)s 调用日志输出函数的模块的文件名 # %(module)s 调用日志输出函数的模块名 # %(funcName)s 调用日志输出函数的函数名 # %(lineno)d 调用日志输出函数的语句所在的代码行 # %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 # %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 # %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 # %(thread)d 线程ID。可能没有 # %(threadName)s 线程名。可能没有 # %(process)d 进程ID。可能没有 # %(message)s用户输出的消息
# -*- coding:utf-8 -*- #创建一个logger对象 #创建一个屏幕管理对象 #创建一文件管理对象 #创建一个格式对象 import logging logger = logging.getLogger() # 创建一个handler,用于写入日志文件 fh = logging.FileHandler('test.log',encoding='utf-8') logger.setLevel(logging.DEBUG) # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S') fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 logger.addHandler(ch) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')
09序列化模块
# -*- coding:utf-8 -*- # json # pickle # shelve # 序列化 ? # 序列 ?有序的结构 # 列表是序列吗?元组 字符串? # 序列化 ? # 实例化、结构化、序列化 # 数据机构 <-正>/反<序列化-> 字符串 #为什么要序列化 #1、文件存储 #2、网络传输 ls = [1,2,3,4] print(repr(str(ls))) s = str(ls) print(list(s)) print(repr(eval(s))) #----eval 问题 #1.对象传输 #2.安全隐患 import json #dump #load #dumps 序列化 ->字符串 #load 反序列化->对象 #序列化 ->字符串 lst = [1,2,3,4,'aaa'] dic = {'a':1,'b':2,'c':3,'d':4} print(lst) print(dic) ret1 = json.dumps(lst) ret2 = json.dumps(dic) print(ret1) print(ret2) # 单双引号区别 # [1, 2, 3, 4, 'aaa'] # {'a': 1, 'b': 2, 'c': 3, 'd': 4} # [1, 2, 3, 4, "aaa"] # {"a": 1, "b": 2, "c": 3, "d": 4} #反序列化->对象 res1 = json.loads(ret1) res2 = json.loads(ret2) print(res1) print(res2) #json 字典的key只能是字符串,并且只能是"引号 dic3 = {('a','b'):1} # ret3 = json.dumps(dic3) # res3 = json.loads(ret3) # print(dic3,ret3,res3) #抛出异常 #json 只支持有限的数据类型:字典,列表,数字类型 #元组会自动转换[] import json #--- # #dump # 只能跟文件相关 # f1 = open('tjson_file','w') # json.dump([1,2,3],f1) # f1.close() # #load # # f2 = open('json_file','r') # c = json.load(f2) # f2.close() # print(c,type(c)) # 需要连续dump 使用dumps # 例如:10个字典 # 分别对每一个字典进行dumps #编码--显示问题 import json f = open('file','w') #json.dump({'国籍':'中国'},f) ret = json.dumps({'国籍':'中国'}) f.write(ret+'\n') #json.dump({'国籍':'美国'},f,ensure_ascii=False) ret = json.dumps({'国籍':'美国'},ensure_ascii=False) f.write(ret+'\n') f.close() #格式化输出 import json data = {'username':['李华','二愣子'],'sex':'male','age':16} json_dic2 = json.dumps(data,sort_keys=True,indent=2,separators=(',',':'),ensure_ascii=False) print(json_dic2) #指定 排序 缩紧 分隔符 #pickle #支持所有数据类型,包括自定义类 #dump #load #dumps 序列化 ->字符串 #load 反序列化->对象 import pickle class A: def __init__(self,name,age): self.name = name self.age = age a = A('aaa',99) f = open('pk_f','wb') p = pickle.dumps(a) pp = pickle.dump(a,f) print(p) f.close() l = pickle.loads(p) print(l.name) f = open('pk_f','rb') ll = pickle.load(f) f.close() print(ll.name) ff = open('pk_f1','wb') pickle.dump({1,2,3,4},ff) pickle.dump({(1,2):456},ff) ff.close() ff1 = open('pk_f1','rb') # print(pickle.load(ff1)) # print(pickle.load(ff1)) #多次DUMP while True: try: print(pickle.load(ff1)) except EOFError: break ff1.close() # json 结果可读,所有语言,数据类型有限 # pickle 结果bytes ,只python,几乎所有 (类必须存在) #pickle -- 存档 ##########shelve ########### import shelve f = shelve.open('shelve_file') f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据 f.close() import shelve f1 = shelve.open('shelve_file') existing = f1['key'] #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错 f1.close() print(existing) #这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB #flag='r' 目前失效 # writeback=True
10模块和包
# -*- coding:utf-8 -*- # bin --> # start.py 只管文件的启动 import os import sys print(sys.path) Base_dir = os.path.dirname(os.path.dirname(__file__)) sys.path.append(Base_dir) # from core import main # main.entry_point # conf --> # -> core - # --> # 核心代码 # db --> # 数据信息 # lib库文件 # 独立的功能 # log # 日志文件 # 项目名最外层

浙公网安备 33010602011771号