---恢复内容开始---
今日内容:
1.包
2.loging模块
3.hashlib模块
4.openpyxl模块
5.深浅拷贝
一 包
模块
三种来源
1.内置的
2.第三方的
3.自定义的
四种表示形态
1.py文件
2.共享库
3.文件夹(一系列模块的结合体)
4.c++编译的连接到python内置的
研究模块与包,还可以站在另外俩个角度分析不同的问题
1.模块的开发者
2.模块的使用者
先看一下模块的执行步骤:
1.创建模块文件的名称空间
2.执行模块文件中的代码,将产生的名字放入模块的名称空间中
3.在执行文件中拿到一个指向模块名称空间的名字
那什么是包:
包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来
需要强调的是:
1、在python3中,即使包下没有__init__.py 文件,import包仍然不会报错,而python2中若是没有的话, 就会报错
2、创建包的目的不是为了运行, 而是被导入使用, 记住,包只是模块的一种形式而已,包的本质就是一种模块
强调
1、在导入时带点, 点的左边必须是一个包, 这是导入包特有的语法
2、包内, 模块直接的导入应该使用from。。。import。。。
3、from。。。import。。。。 import后必须是一个明确的名字, 没有任何的前
导入包的步骤:
先产生一个执行文件的名称空间
1.创建包下面__init__.py文件的名称空间
2.执行包下面__init__.py文件中的代码,将产生的名字放入包下面__init__.py的名称空间中
3.在执行文件中拿到一个指向包下面的__init__.py文件名称空间的名字
注意: 在导入语句中 . 号的左边一定是一个包(文件夹)
当你作为包的设计者来说:
1.当模块的功能特别多的情况下 应该分文件管理
2.每个模块之间为了避免后期模块改名的问题 你可以使用相对导入(包里面的文件都应该是被导入的模块)
站在包的开发者 如果使用绝对路径来管理的自己的模块 那么它只需要永远以包的路径为基准依次导入模块
站在包的使用者 你必须得将包所在的那个文件夹路径添加到system path中(******)
二 logging模块
logging模块简介:
logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。logging模块是Python的一个标准库模块,由标准库模块提供日志记录API的关键好处是所有Python模块都可以使用这个日志记录功能。所以,你的应用日志可以将你自己的日志信息与来自第三方模块的信息整合起来。
logging四大成员:
1.logger对象:负责产生日志
2.filter对象:过滤日志(了解)
3.handler对象:控制日志输出的位置(文件/终端)
4.formmater对象:规定日志内容的格式
logging模块的日志级别:
logging模块默认定义了以下几个日志等级,它允许开发人员自定义其他日志级别,但是这是不被推荐的,尤其是在开发供别人使用的库时,因为这会导致日志级别的混乱。
日志等级 | 描述 |
DEBUG | 告警级别最低,只有在诊断问题时才有兴趣的详细信息。 |
INFO | 告警级别比debug要高,确认事情按预期进行。 |
WARNING | 告警级别比info要高,该模式是默认的告警级别!预示着一些意想不到的事情发生, |
ERROR | 告警级别要比warning要高,由于一个更严重的问题,该软件还不能执行某些功能 |
CRITICAL | 告警级别要比error还要高,严重错误,表明程序本身可能无法继续运行。 |
注意:
1. 开发应用程序或部署开发环境时,可以使用DEBUG或INFO级别的日志获取尽可能详细的日志信息来进行开发或部署调试;应用上线或部署生产环境时,应该使用WARNING或ERROR或CRITICAL级别的日志来降低机器的I/O压力和提高获取错误日志信息的效率。日志级别的指定通常都是在应用程序的配置文件中进行指定的。
2.上面列表中的日志等级是从上到下依次升高的,即:DEBUG < INFO < WARNING < ERROR < CRITICAL,而日志的信息量是依次减少的;
3.当为某个应用程序指定一个日志级别后,应用程序会记录所有日志级别大于或等于指定日志级别的日志信息,而不是仅仅记录指定级别的日志信息,nginx、php等应用程序以及这里要提高的python的logging模块都是这样的。同样,logging模块也可以指定日志记录器的日志级别,只有级别大于或等于该指定日志级别的日志记录才会被输出,小于该等级的日志记录将会被丢弃。
三 hashlib模块
hashlib模块,是用来加密的
1:hash:一种算法, 该算法接受传入的内容,经过运算得到一串 hash值
hash 值得特点是:
只要传入的内容是一样的 得到的hash值必然一样。
不能由hash值返解成内容 ===》把密码做成hash值,不应该在网络传输明文密码
只要使用的hash算法不变, 无论小燕的内容多大, 得到的hash值长度是固定的
应用场景:
hashlib模块应用场景
1.密码的密文存储
2.校验文件内容是否一致
如何加密:
案例:
1 import hashlib # 这个加密的过程是无法解密的 2 md = hashlib.sha3_256() # 生成一个帮你造密文的对象 3 # md.update('hello'.encode('utf-8')) # 往对象里传明文数据 update只能接受bytes类型的数据 4 md.update(b'Jason_@.') # 往对象里传明文数据 update只能接受bytes类型的数据 5 print(md.hexdigest()) # 获取明文数据对应的密文
hashlib模块有很多算法,同常用MD5就够了
1.不同的算法,使用的方法是相同的,密文越长,内部对应的算法越复杂
但是:
1。时间的消耗越大
2.占用空间更大
加密方式分为俩种:普通加密,加盐加密
1.在加密的时候,传入的内容,可以分为多次传入,只要传入的内容相同,
那么生成的密文肯定相同:
案例:
1 import hashlib 2 # 传入的内容 可以分多次传入 只要传入的内容相同 那么生成的密文肯定相同 3 md = hashlib.md5() 4 md.update(b'areyouok?') 5 md.update(b'are') 6 md.update(b'you') 7 md.update(b'ok?') 8 print(md.hexdigest()) # 408ac8c66b1e988ee8e2862edea06cc7 9 # 408ac8c66b1e988ee8e2862edea06cc7
2.加盐加密:
为什么要加盐加密,应为别只要破解了你的密文,就可以拿到你的数据,
加上盐后就算别人破解了你的密文,也拿不到你真正的数据
案例:
1 import hashlib 2 3 md = hashlib.md5() 4 # 公司自己在每一个需要加密的数据之前 先手动添加一些内容 5 md.update(b'oldboy.com') # 加盐处理 6 md.update(b'hello') # 真正的内容 7 print(md.hexdigest())
四.openpyxl模块
openpyxl是一个操作excel表格的模块
1.openpyxl模块的简单操作:
openpyxl中有三个不同层次的类,Workbook是对工作簿的抽象,Worksheet是对表格的抽象,Cell是对单元格的抽象,每一个类都包含了许多属性和方法。
Excel基本操作
操作Excel的一般场景:
1.打开或者创建一个Excel需要创建一个Workbook对象
2.获取一个表则需要先创建一个Workbook对象,然后使用该对象的方法来得到一个Worksheet对象
3.如果要获取表中的数据,那么得到Worksheet对象以后再从中获取代表单元格的Cell对象
Workbook提供的部分常用方法如下:
- get_sheet_names:获取所有表格的名称(新版已经不建议使用,通过Workbook的sheetnames属性即可获取)
- get_sheet_by_name:通过表格名称获取Worksheet对象(新版也不建议使用,通过Worksheet[‘表名‘]获取)
- get_active_sheet:获取活跃的表格(新版建议通过active属性获取)
- remove_sheet:删除一个表格
- create_sheet:创建一个空的表格
- copy_worksheet:在Workbook内拷贝表格
- iter_rows:按行获取所有单元格,内置属性有(min_row,max_row,min_col,max_col)
- iter_columns:按列获取所有的单元格
- append:在表格末尾添加数据
- merged_cells:合并多个单元格
- unmerged_cells:移除合并的单元格
Worksheet提供的部分常用属性如下:
- title:表格的标题
- dimensions:表格的大小,这里的大小是指含有数据的表格的大小,即:左上角的坐标:右下角的坐标
- max_row:表格的最大行
- min_row:表格的最小行
- max_column:表格的最大列
- min_column:表格的最小列
- rows:按行获取单元格(Cell对象) - 生成器
- columns:按列获取单元格(Cell对象) - 生成器
- freeze_panes:冻结窗格
- values:按行获取表格的内容(数据) - 生成器
Cell对象比较简单,常用的属性如下:
- row:单元格所在的行
- column:单元格坐在的列
- value:单元格的值
- coordinate:单元格的坐标
补充:
1 <1>openpyxl的三种最重要的数据结构 2 3 NULL空值:对应于python中的None,表示这个cell里面没有数据。 4 numberic: 数字型,统一按照浮点数来进行处理。对应于python中的float。 5 string: 字符串型,对应于python中的unicode。 6 7 <2>Excel 文件的三个对象 8 9 workbook: 工作簿,一个excel工作簿包含多个sheet。 10 sheet:工作表,一个workbook有多个,表名识别,如“sheet1”,“sheet2”等。 11 cell: 单元格,存储数据对象 12 13 <3>导入 14 15 from openpyxl import Workbook 16 from openpyxl import load_workbook 17 from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Font, Color, Fill 18 from openpyxl.styles import colors 19 from openpyxl.styles import Fill,fills 20 from openpyxl.formatting.rule import ColorScaleRule 21 22 <4>加载workbook 23 24 加载workbook时注意openpyxl只支持xlsx格式,老版的xls格式需要其他方法去加载。 25 wb = load_workbook('file_name.xlsx')或wb = load_workbook(filename = r'file_namexlsx') 26 27 <5>新建worksheet 28 29 新建工作表用函数create_sheet() 30 31 create_sheet(title=None, index=None): 32 """Create a worksheet (at an optional index). 33 :param title: optional title of the sheet 34 :type title: unicode 35 :param index: optional position at which the sheet will be inserted 36 :type index: int 37 38 """ 39 ws1 = wb.create_sheet() #默认插在最后 40 ws2 = wb.create_sheet(0) #插在开头建表后默认名按顺序,如sheet1,sheet2... 41 ws.title = "New Title" #修改表名称 42 简化 ws2 = wb.create_sheet(title="sheet_name") 43 44 <6>打开 worksheet 45 46 1)通过名字 47 ws = wb["sheet_name"] 48 等同于 ws2 = wb.get_sheet_by_name('sheet_name') 49 50 2)不知道名字用index 51 sheet_names = wb.get_sheet_names() 52 ws = wb.get_sheet_by_name(sheet_names[index])# index为0为第一张表 53 54 或者 55 ws =wb.active 56 等同于 ws = wb.get_active_sheet() #通过_active_sheet_index设定读取的表,默认0读第一个表 57 3) 获取活动表表名wb.get_active_sheet().title 58 59 <7>编辑单元格 60 61 1)读写单个单元格 62 c = ws['A4'] #read 等同于 c = ws.cell('A4') 63 ws['A4'] = 4 #write 64 #ws.cell有两种方式,行号列号从1开始 65 d = ws.cell(row = 4, column = 2) #行列读写 66 d = ws.cell('A4') 67 写入cell值 68 ws.cell(row = 4, column = 2).value = 'test') 69 ws.cell(row = 4, column = 2, value = 'test') 70 2)读写多个单元格 71 cell_range = ws['A1':'C2']#读取A1到C1单元格数据 72 get_cell_collection()#读所有单元格数据 73 74 75 <8>获取最大行和最大列 76 77 print(sheet.max_row) 78 print(sheet.max_column) 79 80 <9>获取行和列的值 81 82 sheet.rows为生成器, 里面是每一行的数据,每一行又由一个tuple包裹。 83 sheet.columns类似,不过里面是每个tuple是每一列的单元格。 84 # 按行获取值,返回值为A1, B1, C1这样的顺序 85 for row in sheet.rows: 86 for cell in row: 87 print(cell.value) 88 # 按列获取值,返回值为A1, A2, A3这样的顺序 89 for column in sheet.columns: 90 for cell in column: 91 print(cell.value) 92 上面的代码就可以获得所有单元格的数据。如果要获得某行的数据呢?因sheet.rows是生成器类型,不能使用索引,但是转换成list之后便可使用索引,如list(sheet.rows)[2]这样就获取到第三行的tuple对象。 93 for cell in list(sheet.rows)[2]: 94 print(cell.value) 95 也可以通过iter_rows的参数min_row, max_row指定并获取指定行内容,如下所示,获取第二行表格的内容: 96 97 for row in ws.iter_rows(min_row=2, max_row=2,): 98 line = [cell.value for cell in row] 99 print(line) 100 101 此外可使用方法ws.iter_rows()逐行读取数据 102 ws.iter_rows(range_string=None, row_offset=0, column_offset=0): range-string(string)-单元格的范围:例如('A1:C4') row_offset-添加行 column_offset-添加列 103 # 返回一个生成器, 注意取值时要用value,例如: 104 from openpyxl import load_workbook 105 from constant.constant import CONFIG_PATH 106 import os.path 107 test_data = os.path.join(CONFIG_PATH,'testdata.xlsx') 108 wb = load_workbook(test_data) 109 ws = wb.active 110 ws.title = 'testdata.xlsx' 111 for row in ws.iter_rows('A1:C2'): 112 for cell in row: 113 print(cell.value) 114 115 <10>获取任意区间的值 116 117 法1.使用range函数 118 可以使用range函数,下面的写法,获得了以A1为左上角,B3为右下角矩形区域的所有单元格。注意range从1开始的,因为在openpyxl中为了和Excel中的表达方式一致,并不和编程语言的习惯以0表示第一个值。 119 workbook_path= os.path.join(CONFIG_PATH,'testdata.xlsx') 120 wb = openpyxl.load_workbook(workbook_path) 121 ws = wb.get_sheet_by_name(name='Sheet1') 122 for i in range(1, 4): 123 for j in range(1, 3): 124 print(ws.cell(row=i, column=j)) 125 #out 126 #<Cell 'Sheet1'.A1> 127 #<Cell 'Sheet1'.B1> 128 #<Cell 'Sheet1'.A2> 129 #<Cell 'Sheet1'.B2> 130 #<Cell 'Sheet1'.A3> 131 #<Cell 'Sheet1'.B3> 132 法2.使用切片,如sheet['A1':'B3'],返回一个tuple,该元组内部还是元组,由每行的单元格构成一个元组。 133 134 workbook_path= os.path.join(CONFIG_PATH,'testdata.xlsx') 135 wb = openpyxl.load_workbook(workbook_path) 136 ws = wb.get_sheet_by_name(name='Sheet1') 137 138 for row_cell in ws['A1':'B3']: 139 for cell in row_cell: 140 print(cell) 141 #out 142 #<Cell 'Sheet1'.A1> 143 #<Cell 'Sheet1'.B1> 144 #<Cell 'Sheet1'.A2> 145 #<Cell 'Sheet1'.B2> 146 #<Cell 'Sheet1'.A3> 147 #<Cell 'Sheet1'.B3> 148 149 for cell in sheet['A1':'B3']: 150 print(cell) 151 #out 152 #(<Cell 'Sheet1'.A1>, <Cell 'Sheet1'.B1>) 153 #(<Cell 'Sheet1'.A2>, <Cell 'Sheet1'.B2>) 154 #(<Cell 'Sheet1'.A3>, <Cell 'Sheet1'.B3>)
五 深浅拷贝
值拷贝:
ls = [1, 'abc', [10]]
ls1 = ls # ls1直接将ls中存放的地址拿过来
# ls内部的值发生任何变化,ls1都会随之变化
ls2 = ls.copy() # 新开辟列表空间,但列表中的地址都是直接从ls列表中拿来
# ls内部的可变类型值发生改变,ls2会随之变化
ls3 = deepcopy(ls) # 新开辟列表空间,ls列表中的不可变类型的地址直接拿过来,但是可变类型的地址一定重新开辟空间
# ls内部的所有类型的值发生改变,ls3都不会随之变化