包:
在Python语言中,一个.py文件就可以叫做一个模块。如果a.py中有一个功能在b.py中被引用,那么a.py就算是一个模块。在Python中不止有模块,还有另外一个概念,叫做包(package),包是作为目录存在的,包的另外一个特点就是文件中有一个__init__.py文件,如果我们忘记创建这个文件夹,就没法从这个文件夹里面导入那些模块。在python3中 即使没有__init__.py文件,import 包仍然不会报错,在python2里包里如果没有__init__文件import 包就会报错。 包可以包含模块,也可以包含包。Python中有自带的模块,也有第三方的模块,第三方的模块需要我们自己去进行安装,而Python自身的模块则可以直接导入使用。而我们之所以要使用包,是因为包的本质就是一个文件夹,而文件夹的唯一功能就是将文件组织起来,但是随着功能越写越多,我们无法将所有的功能都放到一个文件中,于是我们就使用了模块去组织功能,而随着模块越来越多,我们就需要用文件夹将文件组织起来,以此来提高程序的结构性和可维护性。
sampling/ # 顶层包
__init__.py # 初始化sampling包
api # 给api分包
__init__.py
policy.py
── versions.py
── cmd # 给cmd分包
── __init__.py
── manage.py
── db # 给db分包
__init__.py
models.py
# 文件内容 包所包含的文件内容
#policy.py
def get():
print('from policy.py')
#versions.py
def create_resource(conf):
print('from version.py: ',conf)
#manage.py
def main():
print('from manage.py')
#models.py
def register_models(engine):
print('from models.py: ',engine)
# 包的使用之import
import glance.db.models
glance.db.models.register_models('mysql')
# 单独导入包名称时不会导入包中所有包含的所有子模块,如:
#在与glance同级的test.py中
import glance
glance.cmd.manage.main()
'''
执行结果:
AttributeError: module 'glance' has no attribute 'cmd'
'''
# 解决方法:
#glance/__init__.py
from . import cmd
#glance/cmd/__init__.py
from . import manage
# 执行:
#在于glance同级的test.py中
import glance
glance.cmd.manage.main()
"""
包的使用之from ... import ...
需要注意的是from后import导入的模块,必须是明确的一个不能带点,
否则会有语法错误,如:from a import b.c是错误语法
"""
from glance.db import models
models.register_models('mysql')
from glance.db.models import register_models
register_models('mysql')
"""
首次导入包:
先产生一个执行文件的名称空间
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模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
1.可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
2.print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出。
"""
1.logger对象:负责产生日志
2.filter对象:过滤日志
3.handler对象:控制日志输出的位置(文件/终端)
4.formmater对象:规定日志内容的格式
"""
import logging
# 1.logger对象:负责产生日志
logger = logging.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(10)
# 8.记录日志
logger.debug('你以为的极限,弄不好只是别人的起点')
hashlib模块:
hashlib是一个提供字符加密功能的模块,包含MD5和SHA的加密算法,具体支持md5,sha1, sha224, sha256, sha384, sha512等算法。 该模块在用户登录认证方面应用广泛,对文本加密也很常见。我们现在常用的大部分都是MD5:
md5算法的特点:
- 压缩性:任意长度的数据,算出的MD5值的长度都是固定的。
- 容易计算:从原数据计算出的MD5值很容易。不管数据多大,很快就能算出一串MD5字符串来。
- 抗修改性:对原数据进行任何改动,哪怕修改任何一个字节,生成的MD5值也有会很大的区别。
- 强抗碰撞:已知原数据和MD5,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
# 基本调用
import hashlib
md = hashlib.md5() #创建hashlib的md5对象
md.update(b"password") #将字符串载入到md5对象中,获得md5算法加密。
print(md.hexdigest()) #通过hexdigest()方法,获得md对象的16进制md5显示。
# 结果为:
5f4dcc3b5aa765d61d8327deb882cf99
# 也可以分段传入:
mport hashlib
md = hashlib.md5()
md.update(b"pass")
md.update(b"word") # 分段传入,但只要传入内容一致,生成的密文肯定一样的。
print(md.hexdigest())
# 结果为:
5f4dcc3b5aa765d61d8327deb882cf99
"""
MD5既然每次生成的值都是固定的,那么就很容易出现密码被破解问题,
这时我们可以通过加盐处理让密码变得更安全。加盐”就是对原密码添加额外的字符串,
然后再生成MD5值,这样就没有办法进行破解了,除非拿到“加盐”字符串。
"""
# MD5加盐方法:
md = hashlib.md5()
md.update(b'salting') # 加盐处理
md.update(b'password') # 真正的内容
print(md.hexdigest())
# 结果为:
e1c9eabdb27775d5f50fa80908bc00e1
# 动态加盐:
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表格的模块
· font(字体类):字号、字体颜色、下划线等
· fill(填充类):颜色等
· border(边框类):设置单元格边框
· alignment(位置类):对齐方式
· number_format(格式类):数据格式
· protection(保护类):写保护
# 创建一个excel 文件,并写入不同类的内容 from openpyxl import Workbook wb = Workbook() ws1 = wb.create_sheet("Mysheet") #创建一个sheet ws1.title = "New Title" #设定一个sheet的名字 ws2 = wb.create_sheet("Mysheet", 0) #设定sheet的插入位置 默认插在后面 ws2.title = u"你好" #设定一个sheet的名字 必须是Unicode ws1.sheet_properties.tabColor = "1072BA" #设定sheet的标签的背景颜色 #获取某个sheet对象 print wb.get_sheet_by_name(u"你好" ) print wb["New Title" ] #获取全部sheet 的名字,遍历sheet名字 print wb.sheetnames for sheet_name in wb.sheetnames: print sheet_name print "*"*50 for sheet in wb: print sheet.title #复制一个sheet wb["New Title" ]["A1"]="zeke" source = wb["New Title" ] target = wb.copy_worksheet(source) # w3 = wb.copy_worksheet(wb['new title']) # ws3.title = 'new2' # wb.copy_worksheet(wb['new title']).title = 'hello' # Save the file wb.save("e:\sample.xlsx") # 操作单元格: from openpyxl import Workbook wb = Workbook() ws1 = wb.create_sheet("Mysheet") #创建一个sheet ws1["A1"]=123.11 ws1["B2"]="你好" d = ws1.cell(row=4, column=2, value=10) print ws1["A1"].value print ws1["B2"].value print d.value # Save the file wb.save("e:\sample.xlsx")
深浅拷贝:
Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果,其实这个是由于共享内存导致的结果拷贝:原则上就是把数据分离出来,复制其数据,并以后修改互不影响。
# 浅拷贝:数据半共享,复制其数据内存独立存放,但是只能拷贝成功第一层。 l1 = [1,2,3,[11,22,33]] l2 = l1.copy() print(l2) #[1,2,3,[11,22,33]] l2[3][2]='aaa' print(l1) #[1, 2, 3, [11, 22, 'aaa']] print(l2) #[1, 2, 3, [11, 22, 'aaa']] l1[0]= 0 print(l1) #[0, 2, 3, [11, 22, 'aaa']] print(l2) #[1, 2, 3, [11, 22, 'aaa']] print(id(l1)==id(l2)) #Flase """ 如上述代码,l2浅拷贝了l1 ,之后l2把其列表中的列表的元素给修改,从结果看出,
l1也被修改了。但是仅仅修改l1列表中的第一层元素,却并没有影响l2。 """ # 深拷贝: #数据完全不共享,复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享。 # 深拷贝就是完完全全复制了一份,且数据不会互相影响,因为内存不共享。 import copy l1 = [1, 2, 3, [11, 22, 33]] l2 = copy.deepcopy(l1) print(l1,'>>>',l2) l2[3][0] = 1111 print(l1,">>>",l2) # 结果为: [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [11, 22, 33]] [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [1111, 22, 33]] # 深拷贝就是数据完完全全独立拷贝出来一份,不会由原先数据变动而变动。