python中的包

包:

在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算法的特点:

  1. 压缩性:任意长度的数据,算出的MD5值的长度都是固定的。
  2. 容易计算:从原数据计算出的MD5值很容易。不管数据多大,很快就能算出一串MD5字符串来。
  3. 抗修改性:对原数据进行任何改动,哪怕修改任何一个字节,生成的MD5值也有会很大的区别。
  4. 强抗碰撞:已知原数据和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]] #
深拷贝就是数据完完全全独立拷贝出来一份,不会由原先数据变动而变动