# coding:utf-8
"""
模块
三种来源
1.内置的
2.第三方的
3.自定义的
四种表示形式
1.py文件(******)
2.共享库
3.文件夹(一系列模块的结合体)(******)
4.C++编译的连接到python内置的
"""
# 研究模块与包 还可以站另外两个角度分析不同的问题
# 1.模块的开发者
# 2.模块的使用者

"""
执行文件调用导入模块时发生的几件事:
先产生一个执行文件的名称空间
1.创建模块文件的名称空间
2.执行模块文件中的代码 将产生的名字放入模块的名称空间中
3.在执行文件中拿到一个指向模块名称空间的名字
"""

"""
什么是包?
它是一系列模块文件的结合体,表示形式就是一个文件夹
该文件夹内部通常会有一个__init__.py文件
包的本质还是一个模块
"""
# from dir.dir1 import p

"""
执行文件导入包,发生的几件事情:
首次导入包:
先产生一个执行文件的名称空间
1.创建包下面的__init__.py文件的名称空间
2.执行包下面的__init__.py文件中的代码 将产生的名字放入包下面的__init__.py文件名称空间中
3.在执行文件中拿到一个指向包下面的__init__.py文件名称空间的名字

在导入语句中 .号的左边肯定是一个包(文件夹)

当你作为包的设计者来说
1.当模块的功能特别多的情况下 应该分文件管理
2.每个模块之间为了避免后期模块改名的问题 你可以使用相对导入(包里面的文件都应该是被导入的模块)

站在包的开发者 如果使用绝对路径来管理的自己的模块 那么它只需要永远以包的路径为基准依次导入模块
站在包的使用者 你必须得将包所在的那个文件夹路径添加到system path中(******)

python2如果要导入包 包下面必须要有__init__.py文件
python3如果要导入包 包下面没有__init__.py文件也不会报错
当你在删程序不必要的文件的时候 千万不要随意删除__init__.py文件

"""









\'\'\'
logging模块的使用
日志的等级 级别高低根据数值排序
logging.debug(\'debug日志\') # 10
logging.info(\'info日志\') # 20
logging.warning(\'warning日志\') # 30
logging.error(\'error日志\') # 40
logging.critical(\'critical日志\') # 50

\'\'\'
# 日志模块:记录
# import logging
#
# logging.basicConfig(filename=\'access.log\',
# format=\'%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s\',
# datefmt=\'%Y-%m-%d %H:%M:%S %p\',
# level=30,
# )
#
#
# logging.debug(\'debug日志\') # 10
# logging.info(\'info日志\') # 20
# logging.warning(\'warning日志\') # 30
# logging.error(\'error日志\') # 40
# logging.critical(\'critical日志\') # 50

"""
1.乱码
2.日志格式
3.如何既打印到终端又写到文件中
"""

# 日志分为五个等级 等级:地震的强度


"""
log生成的几个关键流程 ;

1.logger对象:负责产生日志

2.filter对象:过滤日志(了解)

3.handler对象:控制日志输出的位置(文件/终端)

4.formmater对象:规定日志内容的格式


生成日志的步骤

一 import logging # 导入模块

二 日志对象 = logging.getLogger(\'日志功能名称\')

三 handler对象 = logging.FileHandler(\'日志文件名加后缀在当前路径下\',encoding=\'utf-8\') 指定字符编码,支持中文
handler对象 = logging.StreamHandler() # 输出到终端

四 formmater对象 = logging.Formatter(
fmt=\'字符串形式的当前时间-logger名-文本形式的日志级别-调用日志输出函数的模块名 : 用户输出的消息\',
datefmt=\'年-月-日 时:分:秒 上午下午\',
)
fm1 = logging.Formatter(
fmt=\'%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s\',
datefmt=\'%Y-%m-%d %H:%M:%S %p\',
)

五 给日志对象绑定handler对象,给日志对象绑定输出对象,指定日志输出的文件,字符集
日志对象.addHandler(handler对象)

六 给handler绑定formmate对象,给日志输出对象绑定日志输出格式,只当日志文件或者终端以什么样的格式输出
handler对象.setFormatter(formmater对象)

七 指定日志输出级别,大于等于该级别输出,小于该级别不输出
logger.setLevel(10)

八 记录日志
logger.日志级别(\'日志输出内容\')

"""
#
# import logging # 导入模块
#
# # 1.logger对象:负责产生日志
# logger = logging.getLogger(\'转账记录\') # getlogger做一个日志对象,参数为日志名称
# # 2.filter对象:过滤日志(了解)
#
# # 3.handler对象:控制日志输出的位置(文件/终端)
# hd1 = logging.FileHandler(\'a1.log\',encoding=\'utf-8\') # 输出到文件中
# hd2 = logging.FileHandler(\'a2.log\',encoding=\'utf-8\') # 输出到文件中
# hd3 = logging.StreamHandler() # 输出到终端
#
# # 4.formmater对象:规定日志内容的格式
# fm1 = logging.Formatter(
# fmt=\'%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s\',
# datefmt=\'%Y-%m-%d %H:%M:%S %p\',
# )
# fm2 = logging.Formatter(
# fmt=\'%(asctime)s - %(name)s: %(message)s\',
# datefmt=\'%Y-%m-%d\',
# )
#
# # 5.给logger对象绑定handler对象
# logger.addHandler(hd1)
# logger.addHandler(hd2)
# logger.addHandler(hd3)
#
# # 6.给handler绑定formmate对象
# hd1.setFormatter(fm1)
# hd2.setFormatter(fm2)
# hd3.setFormatter(fm1)
#
# # 7.设置日志等级
# logger.setLevel(20)
#
# # 8.记录日志
# logger.info(\'写了半天 好累啊 好热啊 好想释放\')





\'\'\'
# 日志的配置字典
# 使用日志字典配置

一 import os # 导入os模块跟操作系统打交道,创建目录文件等
二 import logging.config # 到入logging.模块中的 config

三 standard_format = \'[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]\' \
\'[%(levelname)s][%(message)s]\' #其中name为getlogger指定的名字
simple_format = \'[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s\'
设置变量,拼接字符串,显示日志格式,两种格式一种全面一种精简

四 logfile_dir = os.path.dirname(__file__) # log文件的目录 就在执行文件同级目录,就找父目录就可以了,一层
五 logfile_name = \'日志文件名.log\' # log文件名
# 如果不存在定义的日志目录就创建一个

六 if not os.path.isdir(logfile_dir): # 如果日志目录不存在
os.mkdir(logfile_dir) # 日志目录不存在就创建一个
七 logfile_path = os.path.join(logfile_dir, logfile_name)
# 拼接日志文件以及其路径,拼接绝对路径,后面指定输入文件需要用这个变量
*** 四五六七日志文件目录,文件名,拼接文件绝对路径,需要自己手动设置
# log配置字典
八 LOGGING_DIC = {
九 \'version\': 1,
十 \'disable_existing_loggers\': False,
十一 \'formatters\': { # 指定两个日志输出格式 standard simple
\'standard\': {
\'format\': standard_format # 给其赋值为变量,变量为第三步定义的输出格式,这里用变量方便后期修改
},
\'simple\': {
\'format\': simple_format
},
},
十二 \'filters\': {}, # \'filters 过滤日志
十三 \'handlers\': {
#打印到终端的日志
\'console\': { # console 终端
\'level\': \'DEBUG\', # 终端的日志级别
\'class\': \'logging.StreamHandler\', # 打印到屏幕
\'formatter\': \'simple\' # 指定输出格式 simple 需要跟上面指定的key名字一致
},
#打印到文件的日志,收集info及以上的日志
\'default\': { # default 默认打印到文件中
\'level\': \'DEBUG\', # 输入文件的日志级别
\'class\': \'logging.handlers.RotatingFileHandler\', # 保存到文件
\'formatter\': \'standard\', # 指定保存到文件的日志输出格式 standard 需要跟上面指定的一致
\'filename\': logfile_path, # 日志文件以及其路径
\'maxBytes\': 1024*1024*5, # 日志大小 5M 设置日志最大上限
\'backupCount\': 5, # 最多五个日志文件
\'encoding\': \'utf-8\', # 日志文件的编码,再也不用担心中文log乱码了
},
},
十四 \'loggers\': { # 产生log的步骤
#logging.getLogger(__name__)拿到的logger配置
\'日志功能名字\': {
\'handlers\': [\'default\', \'console\'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
\'level\': \'DEBUG\', # 执行输出的日志等级,大于等于10的都输出,可以指定info,大于等于20输出
\'propagate\': True, # 向上(更高level的logger)传递
}, # 当键不存在的情况下 默认都会使用该k:v配置
},
}


十五 logging.config.dictConfig(LOGGING_DIC) # 自动加载字典中的配置 LOGGING_DIC 是配置好的字典
十六 logger1 = logging.getLogger(\'日志功能名字\') # 上面第十四步设置的名字
十七 logger1.debug(\'好好的 不要浮躁 努力就有收获\') # 输出日志内容 debug级别日志,可以修改

\'\'\'
# import os
# import logging.config
#
# # 定义三种日志输出格式 开始
#
# standard_format = \'[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]\' \
# \'[%(levelname)s][%(message)s]\' #其中name为getlogger指定的名字
#
# simple_format = \'[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s\'
#
#
#
# # 定义日志输出格式 结束
# """
# 下面的两个变量对应的值 需要你手动修改
# """
# logfile_dir = os.path.dirname(__file__) # log文件的目录
# logfile_name = \'a3.log\' # log文件名
#
# # 如果不存在定义的日志目录就创建一个
# if not os.path.isdir(logfile_dir):
# os.mkdir(logfile_dir)
#
# # log文件的全路径
# logfile_path = os.path.join(logfile_dir, logfile_name)
# # log配置字典
# LOGGING_DIC = {
# \'version\': 1,
# \'disable_existing_loggers\': False,
# \'formatters\': {
# \'standard\': {
# \'format\': standard_format
# },
# \'simple\': {
# \'format\': simple_format
# },
# },
# \'filters\': {}, # 过滤日志
# \'handlers\': {
# #打印到终端的日志
# \'console\': {
# \'level\': \'DEBUG\',
# \'class\': \'logging.StreamHandler\', # 打印到屏幕
# \'formatter\': \'simple\'
# },
# #打印到文件的日志,收集info及以上的日志
# \'default\': {
# \'level\': \'DEBUG\',
# \'class\': \'logging.handlers.RotatingFileHandler\', # 保存到文件
# \'formatter\': \'standard\',
# \'filename\': logfile_path, # 日志文件
# \'maxBytes\': 1024*1024*5, # 日志大小 5M
# \'backupCount\': 5,
# \'encoding\': \'utf-8\', # 日志文件的编码,再也不用担心中文log乱码了
# },
# },
# \'loggers\': {
# #logging.getLogger(__name__)拿到的logger配置
# \'\': {
# \'handlers\': [\'default\', \'console\'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
# \'level\': \'DEBUG\',
# \'propagate\': True, # 向上(更高level的logger)传递
# }, # 当键不存在的情况下 默认都会使用该k:v配置
# },
# }
#
# # 使用日志字典配置
# logging.config.dictConfig(LOGGING_DIC) # 自动加载字典中的配置
# logger1 = logging.getLogger(\'asajdjdskaj\')
# logger1.debug(\'好好的 不要浮躁 努力就有收获\')









\'\'\'
# hashlib模块 加密的模块
这个加密的过程是无法解密的
传入的内容 可以分多次传入 只要传入的内容相同 那么生成的密文肯定相同

import hashlib # 导入模块
md = hashlib.md5() # 生成一个帮你造密文的对象,加密的工厂,加密模式是md5,可以换别的sha3_256()等
md.update(b\'xiao\') # 加盐处理 公司自己在每一个需要加密的数据之前,先手动添加一些内容,可以是每次不一样的内容
md.update(\'hello\'.encode(\'utf-8\')) # 往对象里传的是明文数据 update只能接受bytes类型的数据,需要encode
md.update(b\'hello\') # 往对象里传的是明文数据 update只能接受bytes类型的数据,需要encode
以上三次update都是往造密文的对象中添加明文内容,分多次传入跟一次传入是一样的,下面获取的密文是三个明文的结果
print(md.hexdigest()) # 获取明文数据对应的密文 # 打印加密之后的到的MD5值

应用:
可以写成一个加密函数,获取密文的函数,将用户注册输入的密码加密存储,登录时再调函数,加密明文再和存储做密文比较
import hashlib
def get_md5(data):
md = hashlib.md5()
md.update(\'加盐\'.encode(\'utf-8\'))
md.update(data.encode(\'utf-8\'))
return md.hexdigest()

password = input(\'password>>>:\')
res = get_md5(password)
print(res)

\'\'\'
# import hashlib # 这个加密的过程是无法解密的
# md = hashlib.sha3_256() # 生成一个帮你造密文的对象
# # md.update(\'hello\'.encode(\'utf-8\')) # 往对象里传明文数据 update只能接受bytes类型的数据
# md.update(b\'Jason_@.\') # 往对象里传明文数据 update只能接受bytes类型的数据
# print(md.hexdigest()) # 获取明文数据对应的密文

# 撞库
"""
1.不用的算法 使用方法是相同的
密文的长度越长 内部对应的算法越复杂
但是
1.时间消耗越长
2.占用空间更大
通常情况下使用md5算法 就可以足够了
"""


# import hashlib
# # 传入的内容 可以分多次传入 只要传入的内容相同 那么生成的密文肯定相同
# md = hashlib.md5()
# md.update(b\'areyouok?\')
# md.update(b\'are\')
# md.update(b\'you\')
# md.update(b\'ok?\')
# print(md.hexdigest()) # 408ac8c66b1e988ee8e2862edea06cc7
# 408ac8c66b1e988ee8e2862edea06cc7
"""
hashlib模块应用场景
1.密码的密文存储
2.校验文件内容是否一致
"""

# 加盐处理
# import hashlib
#
# md = hashlib.md5()
# # 公司自己在每一个需要加密的数据之前 先手动添加一些内容
# md.update(b\'oldboy.com\') # 加盐处理
# md.update(b\'hello\') # 真正的内容
# print(md.hexdigest())


# 动态加盐

# import hashlib
#
# def get_md5(data):
# md = hashlib.md5()
# md.update(\'加盐\'.encode(\'utf-8\'))
# md.update(data.encode(\'utf-8\'))
# return md.hexdigest()
#
#
# password = input(\'password>>>:\')
# res = get_md5(password)
# print(res)










\'\'\'
# openpyxl 比较火的操作excel表格的模块
\'\'\'

"""
03版本之前 excel文件的后缀名 叫xls
03版本之后 excel文件的后缀名 叫xlsx

xlwd 写excel
xlrt 读excel

xlwd和xlrt既支持03版本之前的excel文件也支持03版本之后的excel文件
openpyxl 只支持03版本之后的 xlsx


写文件
from openpyxl import Workbook # 导入工作簿的写功能
工作簿名 = Workbook() # 先生成一个工作簿 会创建一个
工作簿名 = wb.create_sheet(\'sheet名\',从0开始第几个sheet) # 创建一个表单页 后面可以通过数字控制位置
sheet.title = \'新sheet名\' # 后期可以通过表单页对象点title修改表单页名称
工作簿名[\'A3\'] = 值 # A列第三行
工作簿名[\'A5\'] = \'=sum(A3:A4)\' # excel求和函数 # A列第五行
工作簿名.cell(row=6,column=3,value=88888888) # 根据坐标添加值
工作簿名.append([\'值1\',\'值2\',\'值3\']) # 添加到第一行的ABC
工作簿名.save(\'文件名.xlsx\') # 保存表格和内容,并指定文件名 另存为



读文件
from openpyxl import load_workbook # 导入工作簿的读功能
wb = load_workbook(\'test.xlsx\',read_only=True,data_only=True)
print(wb.sheetnames) # [\'login\', \'Sheet\', \'index1\'] 看表格里面都有那些sheet,并返回列表
print(wb[\'login\'][\'A3\'].value) # 打印 (指定文件的指定sheet的指定坐标的.value值) 取值
print(wb[\'login\'][\'A5\'].value) # 通过代码产生的excel表格必须经过人为操作之后才能读取出函数计算出来的结果值 A5是函数

# res = wb[\'login\']
# # print(res)
# ge1 = res.rows
# for i in ge1:
# for j in i:
# print(j.value)

"""


# 写
# from openpyxl import Workbook
#
#
# wb = Workbook() # 先生成一个工作簿
# wb1 = wb.create_sheet(\'index\',0) # 创建一个表单页 后面可以通过数字控制位置
# wb2 = wb.create_sheet(\'index1\')
# wb1.title = \'login\' # 后期可以通过表单页对象点title修改表单页名称
#
# wb1[\'A3\'] = 666
# wb1[\'A4\'] = 444
# wb1.cell(row=6,column=3,value=88888888)
# wb1[\'A5\'] = \'=sum(A3:A4)\'
#
# wb2[\'G6\'] = 999
# wb1.append([\'username\',\'age\',\'hobby\'])
# wb1.append([\'jason\',18,\'study\'])
# wb1.append([\'tank\',72,\'吃生蚝\'])
# wb1.append([\'egon\',84,\'女教练\'])
# wb1.append([\'sean\',23,\'会所\'])
# wb1.append([\'nick\',28,])
# wb1.append([\'nick\',\'\',\'秃头\'])

# 保存新建的excel文件
# wb.save(\'test.xlsx\')


# from openpyxl import load_workbook # 读文件
#
#
# wb = load_workbook(\'test.xlsx\',read_only=True,data_only=True)
# # print(wb)
# # print(wb.sheetnames) # [\'login\', \'Sheet\', \'index1\']
# # print(wb[\'login\'][\'A3\'].value)
# # print(wb[\'login\'][\'A4\'].value)
# # print(wb[\'login\'][\'A5\'].value) # 通过代码产生的excel表格必须经过人为操作之后才能读取出函数计算出来的结果值
#
# wb = load_workbook(\'test.xlsx\',read_only=True,data_only=True)
# res = wb[\'login\']
# # print(res)
# ge1 = res.rows
# for i in ge1:
# for j in i:
# print(j.value)





\'\'\'
深浅拷贝
深浅拷贝对于不可变类型,原数据和副本都指向同一内存地址中的值
深浅拷贝的区别在于对于不可变类型,指向原来(浅拷贝),还是自己创建一个新的可变类型(深拷贝)

浅拷贝:副本 = copy.copy(原数据) 之后
原数据中的不可变类型跟副本中的不可变类型在内存中是同一个值
副本中的不可变类型还是指向原数据指向的内存中的值

原数据中的可变类型跟副本中的可变类型在内存中是同一个值
副本中的可变类型也还是指向原数据指向的内存中的值
修改原数据中不可变类型,副本数据不变
修改原数据中可变类型,副本数据也会变


深拷贝:副本 = copy.deepcopy(原数据) 之后,
原数据中的不可变类型跟副本中的不可变类型在内存中是同一个值
副本中的不可变类型还是指向原数据指向的内存中的值

原数据中的可变类型跟副本中的可变类型在内存中是不同的两个值
副本中的可变类型会新建一个根源数据一样的不可变类型,可变类型中的不可变类型还是指向原数据
修改原数据中不可变类型,副本数据不变
修改原数据中可变类型,副本数据不会变
修改原数据的可变类型的不可变类型,副本数据可变类型中的不可变类型会一起改变
\'\'\'
# import copy
# l = [1,2,[1,2]]
# l1 = l
# print(id(l),id(l1))
# l1 = copy.copy(l) # 拷贝一份 ....... 浅拷贝
# print(id(l),id(l1))
# l[0] = 222
# print(l,l1)
# l[2].append(666)
# print(l,l1)
# l1 = copy.deepcopy(l)
# l[2].append(666)
# print(l,l1)







































































版权声明:本文为xiaozhenpy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xiaozhenpy/p/11220623.html