随机数模块python
randint:获得一个随机数mysql
import random # 导入一个模块 v = random.randint(起始,终止) # 获得一个随机数 #示例:生成随机验证码 import random def get_random_code(length=6): data = [] for i in range(length): v = random.randint(65,90) data.append(chr(v)) return ''.join(data) code = get_random_code() print(code)
# 将指定的 “字符串” 进行 加密 import hashlib # 导入一个模块 def get_md5(data): # md5 加密函数 obj = hashlib.md5() obj.update(data.encode('utf-8')) result = obj.hexdigest() return result val = get_md5('123') print(val) # 加盐 import hashlib def get_md5(data): obj = hashlib.md5("sidrsdxff123ad".encode('utf-8')) # 加盐 obj.update(data.encode('utf-8')) result = obj.hexdigest() return result val = get_md5('123') print(val)
# 应用:用户注册+用户登陆 import hashlib USER_LIST = [] def get_md5(data): # md5 加密函数 obj = hashlib.md5("12:;idrsicxwersdfsaersdfs123ad".encode('utf-8')) # 加盐 obj.update(data.encode('utf-8')) result = obj.hexdigest() return result def register(): # 用户注册函数 print('**************用户注册**************') while True: user = input('请输入用户名:') if user == 'N': return pwd = input('请输入密码:') temp = {'username':user,'password':get_md5(pwd)} USER_LIST.append(temp) def login(): # 用户登陆函数 print('**************用户登录**************') user = input('请输入用户名:') pwd = input('请输入密码:') for item in USER_LIST: if item['username'] == user and item['password'] == get_md5(pwd): return True register() result = login() if result: print('登录成功') else: print('登录失败')
sha程序员
import hashlib md5 = hashlib.sha1('盐'.encode()) md5.update(b'str') print(md5.hexdigest())
只能在终端运行web
getpass.getpass:输入密码时不显示正则表达式
import getpass # 导入一个模块 pwd = getpass.getpass('请输入密码:') if pwd == '123': print('输入正确')
时间模块redis
time.time:时间戳(从1970年到如今经历的秒数)算法
# https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=4ZwIFHM6iw==&tip=1&r=-781028520&_=1555559189206
time.sleep:等待的秒数sql
time.timezonejson
示例app
# 计算函数执行时间 import time def wrapper(func): def inner(): start_time = time.time() v = func() end_time = time.time() print(end_time-start_time) return v return inner @wrapper def func1(): time.sleep(2) print(123) func1()
时间模块
datetime.now():当前本地时间
datetime.utcnow():当前UTC时间
import time from datetime import datetime,timezone,timedelta # 获取datetime格式时间 # 当前本地时间 v1 = datetime.now() # 当前东7区时间 tz = timezone(timedelta(hours=7)) v2 = datetime.now(tz) # 当前UTC时间 v3 = datetime.utcnow() print(v3)
相互转换
import time from datetime import datetime,timedelta # 1.datetime格式和字符串的相互转换 # 把datetime格式转换成字符串:strftime v1 = datetime.now() val = v1.strftime("%Y-%m-%d %H:%M:%S") # 字符串转成datetime格式:strptime v1 = datetime.strptime('2011-11-11','%Y-%m-%d') # 2.datetime时间的加减 v1 = datetime.strptime('2011-11-11','%Y-%m-%d') v2 = v1 - timedelta(days=140) # 再转换成字符串 date = v2.strftime('%Y-%m-%d') # 3.时间戳和datetime的相互转换 # 时间戳转换成datetime格式:fromtimestamp ctime = time.time() v1 = datetime.fromtimestamp(ctime) # datetime格式转换成时间戳:timestamp v1 = datetime.now() val = v1.timestamp()
python解释器相关数据
sys.getrefcount:获取一个值的应用计数
sys.getrecursionlimit:python默认支持的递归数量
sys.stdout.write:输入输出
补充:\n:换行 \t:制表符 \r:回到当前行的起始位置
import time for i in range(1,101): msg = "%s%%\r" %i print(msg,end='') time.sleep(0.05)
示例:读取文件的进度条
import os # 1. 读取文件大小(字节) file_size = os.stat('20190409_192149.mp4').st_size # 2.一点一点的读取文件 read_size = 0 with open('20190409_192149.mp4',mode='rb') as f1,open('a.mp4',mode='wb') as f2: while read_size < file_size: chunk = f1.read(1024) # 每次最多去读取1024字节 f2.write(chunk) read_size += len(chunk) val = int(read_size / file_size * 100) print('%s%%\r' %val ,end='')
sys.argv:获取用户执行脚本时,传入的参数
""" 让用户执行脚本传入要删除的文件路径,在内部帮助用将目录删除。 C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py """ import sys # 获取用户执行脚本时,传入的参数。 # C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test # sys.argv = [D:/code/s21day14/7.模块传参.py, D:/test] path = sys.argv[1] # 删除目录 import shutil shutil.rmtree(path)
sys.exit(0):程序终止,0表明正常终止
sys.path:默认python去导入模块时,会按照sys.path中的路径
import sys sys.path.append('D:\\')
sys.modules:存储了当前程序中用到的全部模块,反射本文件中的内容
和操做系统相关的数据
os.path.exists(path):若是path存在,返回True;若是path不存在,返回False
os.stat('文件路径').st_size:获取文件大小
os.path.abspath():获取一个文件的绝对路径
import os v1 = os.path.abspath(path) print(v1)
os.path.dirname():获取路径的上级目录
import os v = r"D:\code\s21day14\20190409_192149.mp4" print(os.path.dirname(v))
补充:转义
v1 = r"D:\code\s21day14\n1.mp4" (推荐) v2 = "D:\\code\\s21day14\\n1.mp4"
os.path.join:路径的拼接
import os path = "D:\code\s21day14" # user/index/inx/fasd/ v = 'n.txt' result = os.path.join(path,v) print(result)
os.listdir:查看一个目录下全部的文件【第一层】
import os result = os.listdir(r'D:\code\s21day14') for path in result: print(path)
os.walk:查看一个目录下全部的文件【全部层】
import os result = os.walk(r'D:\code\s21day14') for a,b,c in result: # a,正在查看的目录 b,此目录下的文件夹 c,此目录下的文件 for item in c: path = os.path.join(a,item) print(path)
os.makedir:建立目录,只能生产一层目录(基本不用这个)
os.makedirs:建立目录及其子目录(推荐使用)
# 将内容写入指定文件中 import os file_path = r'db\xx\xo\xxxxx.txt' file_folder = os.path.dirname(file_path) if not os.path.exists(file_folder): os.makedirs(file_folder) with open(file_path,mode='w',encoding='utf-8') as f: f.write('asdf')
os.rename:重命名
# 将db重命名为sb import os os.rename('db','sb')
os.path.isdir:判断是不是文件夹
os.path.isfile:判断是不是文件
用途:删除、重命名、压缩、解压等
shutil.rmtree(path):删除目录
# 删除目录 import shutil shutil.rmtree(path)
shutil.move:重命名
# 重命名 import shutil shutil.move('test','ttt')
shutil.make_archive:压缩文件
# 压缩文件 import shutil shutil.make_archive('zzh','zip','D:\code\s21day16\lizhong')
shutil.unpack_archive:解压文件
# 解压文件 import shutil shutil.unpack_archive('zzh.zip',extract_dir=r'D:\code\xxxxxx\xxxx',format='zip')
示例
import os import shutil from datetime import datetime ctime = datetime.now().strftime('%Y-%m-%d-%H-%M-%S') # 1.压缩lizhongwei文件夹 zip # 2.放到到 code 目录(默认不存在) # 3.将文件解压到D:\x1目录中。 if not os.path.exists('code'): os.makedirs('code') shutil.make_archive(os.path.join('code',ctime),'zip','D:\code\s21day16\lizhongwei') file_path = os.path.join('code',ctime) + '.zip' shutil.unpack_archive(file_path,r'D:\x1','zip')
json.dumps():序列化
import json v = {'k1':'alex','k2':'李杰'} val = json.dumps(v,ensure_ascii = False)
json.loads():反序列化
import json # 序列化,将python的值转换为json格式的字符串。 v = [12,3,4,{'k1':'v1'},True,'asdf'] v1 = json.dumps(v) print(v1) # 反序列化,将json格式的字符串转换成python的数据类型 v2 = '["alex",123]' print(type(v2)) v3 = json.loads(v2) print(v3,type(v3))
json.dump:打开文件,序列化后,写入文件
import json v = {'k1':'alex','k2':'李杰'} f = open('x.txt',mode='w',encoding='utf-8') val = json.dump(v,f) print(val) f.close()
json.load:打开文件,读取文件内容
import json v = {'k1':'alex','k2':'李杰'} f = open('x.txt',mode='r',encoding='utf-8') data = json.load(f) f.close() print(data,type(data))
pickle.dumps:序列化
pickle.loads:反序列化
import pickle # 序列化 v = {1,2,3,4} val = pickle.dumps(v) print(val) # 反序列化 data = pickle.loads(val) print(data,type(data))
pickle.dump:写入文件(注意:mode='wb')
pickle.load:读取文件(注意:mode='rb')
import pickle # 写入文件 v = {1,2,3,4} f = open('x.txt',mode='wb') val = pickle.dump(v,f) f.close() # 读取文件 f = open('x.txt',mode='rb') data = pickle.load(f) f.close() print(data)
拷贝模块
copy.copy:浅拷贝
copy.deepcopy:深拷贝
import copy v1 = [1,2,3] v2 = copy.copy(v1) #浅拷贝 v3 = copy.deepcopy(v1) #深拷贝
importlib.import_module:经过字符串的形式导入模块
#示例一: import importlib # 用字符串的形式导入模块。 redis = importlib.import_module('utils.redis') # 用字符串的形式去对象(模块)找到他的成员。 getattr(redis,'func')() #示例二: import importlib middleware_classes = [ 'utils.redis.Redis', # 'utils.mysql.MySQL', 'utils.mongo.Mongo' ] for path in middleware_classes: module_path,class_name = path.rsplit('.',maxsplit=1) module_object = importlib.import_module(module_path)# from utils import redis cls = getattr(module_object,class_name) obj = cls() obj.connect()
日志模块:记录日志的
日志处理本质:Logger / FileHandler / Formatter
两种配置方式:
basicConfig
logger对象
import logging # 建立一个logger对象 logger = logging.getLogger() # 建立一个文件操做符 fh = logging.FileHandler('log.log') # 建立一个屏幕操做符 sh = logging.StreamHandler() # 给logger对象绑定 文件操做符 logger.addHandler(fh) # 给logger对象绑定 屏幕操做符 logger.addHandler(sh) # 建立一个格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 给文件操做符 设定格式 fh.setFormatter(formatter) # 给屏幕操做符 设定格式 sh.setFormatter(formatter) # 用logger对象来操做 logger.warning('message')
日志异常级别
CRITICAL = 50 # 崩溃 FATAL = CRITICAL ERROR = 40 # 错误 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0
推荐处理日志方式
import logging file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',) logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', handlers=[file_handler,], level=logging.ERROR ) logging.error('你好')
推荐处理日志方式 + 日志分割
import time import logging from logging import handlers # file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',) file_handler = handlers.TimedRotatingFileHandler(filename='x3.log', when='s', interval=5, encoding='utf-8') logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', handlers=[file_handler,], level=logging.ERROR ) for i in range(1,100000): time.sleep(1) logging.error(str(i))
注意事项:
# 在应用日志时,若是想要保留异常的堆栈信息。 import logging import requests logging.basicConfig( filename='wf.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', level=logging.ERROR ) try: requests.get('http://www.xxx.com') except Exception as e: msg = str(e) # 调用e.__str__方法 logging.error(msg,exc_info=True)
OrderedDict:有序字典
from collections import OrderedDict odic = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(odic) for k in odic: print(k,odic[k])
defaultdict:默认字典
deque:双端队列
namedtuple:可命名元组
# 建立一个类,这个类没有方法,全部属性的值都不能修改 from collections import namedtuple # 可命名元组 Course = namedtuple('Course',['name','price','teacher']) python = Course('python',19800,'alex') print(python) print(python.name) print(python.price)
定义
正则规则
元字符
量词
+
:表示匹配1次或屡次*
:表示匹配0次或屡次,表示无关紧要,可是有能够有多个好比小数点后n位贪婪匹配
而后只须要在正则和待匹配的字符串外面都加r便可
邮箱规则 @以前必须有内容且只能是字母(大小写)、数字、下划线(_)、减号(-)、点(.) @和最后一个点(.)之间必须有内容且只能是字母(大小写)、数字、点(.)、减号(-),且两个点不能挨着 最后一个点(.)以后必须有内容且内容只能是字母(大小写)、数字且长度为大于等于2个字节,小于等于6个字节 邮箱验证的正则表达式: ^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$
re.findall:会匹配字符串中全部符合规则的项,并返回一个列表,若是没匹配到,返回空列表
import re ret = re.findall('\d+','alex83') print(ret) # findall 会匹配字符串中全部符合规则的项 # 并返回一个列表 # 若是未匹配到返回空列表
re.search:若是匹配到,返回一个对象,用group取值,若是没匹配到,返回None,不能用group
import re ret = re.search('\d+','alex83') print(ret) # 若是能匹配上返回一个对象,若是不能匹配上返回None if ret: print(ret.group()) # 若是是对象,那么这个对象内部实现了group,因此能够取值 # 若是是None,那么这个对象不可能实现了group方法,因此报错 # 会从头至尾从带匹配匹配字符串中取出第一个符合条件的项 # 若是匹配到了,返回一个对象,用group取值 # 若是没匹配到,返回None,不能用group
re.match:match = search + ^正则
import re ret = re.match('\d','alex83') == re.match('^\d','alex83') print(ret) # 会从头匹配字符串,从第一个字符开始是否符合规则 # 若是符合,就返回对象,用group取值 # 若是不符合,就返回None
re.finditer:在查询的结果超过1个的状况下,可以有效的节省内存,下降空间复杂度,从而也下降了时间复杂度
import re ret = re.finditer('\d','safhl02urhefy023908'*20000000) # ret是迭代器 for i in ret: # 迭代出来的每一项都是一个对象 print(i.group()) # 经过group取值便可
re.compile:在同一个正则表达式重复使用屡次的时候使用可以减小时间的开销
import re ret = re.compile('\d+') r1 = ret.search('alex83') r2 = ret.findall('wusir74') r3 = ret.finditer('taibai40') for i in r3: print(i.group())
re.split:利用正则规则进行切割
import re ret = re.split('\d(\d)','alex83wusir74taibai') # 默认自动保留分组中的内容 print(ret)
re.sub / re.subn:利用正则规则进行替换
import re ret = re.sub('\d','D','alex83wusir74taibai',1) print(ret) # 'alexD3wusir74taibai' ret = re.subn('\d','D','alex83wusir74taibai') print(ret) # ('alexDDwusirDDtaibai', 4)
分组和re模块
关于group取值
import re ret = re.search('<(\w+)>(.*?)</\w+>',s1) print(ret) print(ret.group(0)) # group参数默认为0 表示取整个正则匹配的结果 print(ret.group(1)) # 取第一个分组中的内容 print(ret.group(2)) # 取第二个分组中的内容
分组命名:(?P <名字> 正则表达式)
import re ret = re.search('<(?P<tag>\w+)>(?P<cont>.*?)</\w+>',s1) print(ret) print(ret.group('tag')) # 取tag分组中的内容 print(ret.group('cont')) # 取cont分组中的内容
引用分组:(?P=组名) 这个组中的内容必须彻底和以前已经存在的组匹配到的内容如出一辙
import re # 方法一: s = '<h1>wahaha</h1>' ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',s) print(ret.group('tag')) # 'h1' # 方法二: s = '<h1>wahaha</h1>' ret = re.search(r'<(\w+)>.*?</\1>',s) print(ret.group(1)) # 'h1'
分组和findall:默认findall 优先显示分组内的内容,取消分组优先显示 :(?:正则)
import re ret = re.findall('\d(\d)','aa1alex83') # findall遇到正则表达式中的分组,会优先显示分组中的内容 print(ret) # 取消分组优先显示: ret = re.findall('\d+(?:\.\d+)?','1.234+2') print(ret)
有的时候咱们想匹配的内容包含在不相匹配的内容当中,这个时候只须要把不想匹配的先匹配出来,再经过手段去掉
import re 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('') print(ret) # ['1', '2', '60', '5', '4', '3']
爬虫示例
# 方法一: import re import json import requests def parser_page(par,content): res = par.finditer(content) for i in res: yield {'id': i.group('id'), 'title': i.group('title'), 'score': i.group('score'), 'com_num': i.group('comment_num')} def get_page(url): ret = requests.get(url) return ret.text pattern = '<div class="item">.*?<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?' \ '<span class="rating_num".*?>(?P<score>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>' par = re.compile(pattern,flags=re.S) num = 0 with open('movie_info',mode = 'w',encoding='utf-8') as f: for i in range(10): content = get_page('https://movie.douban.com/top250?start=%s&filter=' % num) g = parser_page(par,content) for dic in g: f.write('%s\n'%json.dumps(dic,ensure_ascii=False)) num += 25
# 方法二:进阶 import re import json import requests def parser_page(par,content): res = par.finditer(content) for i in res: yield {'id': i.group('id'), 'title': i.group('title'), 'score': i.group('score'), 'com_num': i.group('comment_num')} def get_page(url): ret = requests.get(url) return ret.text def write_file(file_name): with open(file_name,mode = 'w',encoding='utf-8') as f: while True: dic = yield f.write('%s\n' % json.dumps(dic, ensure_ascii=False)) pattern = '<div class="item">.*?<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?' \ '<span class="rating_num".*?>(?P<score>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>' par = re.compile(pattern,flags=re.S) num = 0 f = write_file('move2') next(f) for i in range(10): content = get_page('https://movie.douban.com/top250?start=%s&filter=' % num) g = parser_page(par,content) for dic in g: f.send(dic) num += 25 f.close()