常用模块>包

2018-09-04  本文已影响0人  Snackk
序列化模块
序列
什么叫序列化
为什么要把一个数据类型序列化?
import json
stu = {'name':'何青松','sex':'male'}
ret = json.dumps(stu)  # 序列化的过程,将一个字典转换成一个字符串
print(stu,type(stu))
print(ret,type(ret))

d = json.loads(ret)    # 反序列化的过程,将一个字符串格式的字典转换成一个字典
print('d-->',d,type(d))
def func(dic):
    with open('json_file','a',encoding='utf-8') as f:
        res = json.dumps(dic,ensure_ascii=False)
        f.write('%s\n'%res)

dic = {'k1':'v1','k2':'v2','k3':'何青松'}
func(dic)
import json
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)  #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()

f = open('json_file')
dic2 = json.load(f)  #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)
import json
data = {'username':['李华','二愣子'],'sex':'male','age':16}
json_dic2 = json.dumps(data,sort_keys=True,indent=2,separators=(',',':'),ensure_ascii=False)#sort_keys,字符编码排序 #indent=2默认换行空格# separators格式化
print(json_dic2)
json的优点
缺点
import pickle
stu = {'name':'何青松','sex':'male',1:('a','b')}
ret = pickle.dumps(stu)
print(ret)
d = pickle.loads(ret)
print(d,type(d))
class Course():
    def __init__(self,name,price):
        self.name = name
        self.price = price

python = Course('python',29800)
ret = pickle.dumps(python)
print(ret)

p = pickle.loads(ret)
print(p.name,p.price)
import pickle
class Course():
    def __init__(self,name,price):
        self.name = name
        self.price = price

python = Course('python',29800)
linux = Course('linux',25800)
mysql = Course('mysql',18000)
ret = pickle.dumps(python)
print(ret)

p = pickle.loads(ret)
print(p.name,p.price)

with open('pickle_file','wb') as f:
    pickle.dump(python,f)

with open('pickle_file','rb') as f:
    course = pickle.load(f)
print(course.name)
pickle
    dump
    load
        操作文件文件必须以+b打开
    在load的时候 如果这个要被load的内容所在的类不在内存中,会报错
    pickle支持多次dump和多次load(需要异常处理)
pickle 能不能多次 dump
总结:
内置方法
    __new__ :
        构造方法,在对象实例化的时候帮助对象开辟一块儿空间
        __new__ 比init先执行
        单例模式
    __del__: 析构方法
        删除一个对象之前调用
    __eq__ : obj1 == obj2  obj1.__eq__(obj2)
    __len__:len(obj)
    __hash__:# 一种算法,把一个对象转换成一个数字
        字典的一次寻址
        set去重
模块
    三种:
        内置模块
        第三方模块
        自定义模块
    序列化模块 把数据类型 -->  str、bytes
        数据的持久化存储 :文件存储
        数据的网络传输
        json
            所有语言都支持
            支持的数据类型有限
        pickle
            只有python语言支持
            支持几乎所有的数据类型
时间模块

import time

import time
print(time.localtime())  #显示结构化时间  得到的是北京时间 开始于1970-1-1  8:0:0
print(time.gmtime()) #得到的是伦敦时间  开始于1970-1-1  0:0:0
print(time.time())    #显示时间戳
print(time.strftime('%Y-%m-%d %X'))  #显示格式化时间
print(time.strptime('2018-8-8','%Y-%m-%d'))  # 转化格式化时间到结构化时间

计算本月1号的时间戳时间

import  time
def get_timestamp():
    time1 = time.strftime('%Y-%m-1')
    time2 = time.strptime(time1,'%Y-%m-%d')
    time3 = time.mktime(time2)
    return time3

print(get_timestamp())
随机数模块

import random

print(random.random()) #(0,1) 默认0到1之间
print(random.uniform(2,3)) #(n,m) n 到 m 之间

随机生成n位数的数字验证码

def get_code(n):
    code = ''
    for i in range(n):
        num = random.randint(0,9)
        code += str(num)
    return code

print(get_code(6))

65-90 A-Z 字符编码数 chr() 内置函数
97-122 a-z

生成6位验证码

def get_code(n=6):
    code = ''
    for i in range(n):
        num = str(random.randint(0,9))
        alpha_upper = chr(random.randint(65, 90))
        alpha_lower = chr(random.randint(97, 122))
        c = random.choice([num,alpha_upper,alpha_lower])
        code += c
    return code

进阶

def get_code(n = 6 ,alph_flag = True):
    code = ''
    for i in range(n):
        c = str(random.randint(0,9))
        if alph_flag:
            alph_A = chr(random.randint(65,90))
            alph_a = chr(random.randint(97,122))
            c = random.choice([c,alph_A,alph_a])
        code += c
    return code
print(get_code(alph_flag=False))
OS模块

os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印

os.stat('path/filename') 获取文件/目录信息

stat 结构:

st_mode: inode 保护模式
st_ino: inode 节点号。
st_dev: inode 驻留的设备。
st_nlink: inode 的链接数。
st_uid: 所有者的用户ID。
st_gid: 所有者的组ID。
st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
st_atime: 上次访问的时间。
st_mtime: 最后一次修改的时间。
st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。

os.path.abspath(path) 返回path规范化的绝对路径 path可以是相对如今也可以是绝对路径,相对路径要在当前目录下

os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如果path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素

os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False

os.path.isabs(path) 如果path是绝对路径,返回True

os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False

os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 可能和os.path.abspath 拼接完再规范化

os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间

os.path.getsize(path) 返回path的大小(文件大小)

os.system("bash command") # - 以字符串的形式来执行操作系统的命令 运行shell命令,直接显示
exec - 以字符串的形式来执行python代码

os.popen("bash command).read() 运行shell命令,获取执行结果
eval 以字符串的形式来执行python代码 且返回结果

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
print(os.getcwd())
open('file','w').close() # 文件在执行这个文件的目录下创建了
不是当前被执行的文件所在的目录,而是执行这个文件所在的目录
工作目录在哪儿,所有的相对目录文件的创建,都是在哪儿执行这个文件,就在哪儿创建

os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
改变os.getcwd() 操作系统特性

os.chdir('D:\骑士计划PYTHON1期\day23')
open('file3','w').close()
print('-->cwd : ',os.getcwd())
print(__file__)   #当前文件的绝对路径

sys.modules 查看当前内存空间中所有的模块,和这个模块的内存空间

print(sys.path)
一个模块能否被导入,就看这个模块所在的目录在不在sys.path路径中
内置模块和第三方扩展模块都不需要我们处理sys.path就可以直接使用
自定义的模块的导入工作需要自己手动的修改sys.path


总结:

time模块
时间戳格式 浮点型
结构化时间 元组
格式化时间 字符串
    '%Y %m % d %H %M %S'
时间戳时间 -localtime/gmtime->  结构化时间 -strftime-> 格式化时间
时间戳时间 <-mktime-  结构化时间 <-strptime- 格式化时间
random模块
random.random 随机小数(0,1)
random.uniform 随机小数(n,m)
random.randint 随机整数 [n,m]
random.randrange(start,end,step)  随机整数 [n:m:s)
random.choice(list/range/tuple/str) 随机抽取一个值
random.sample(list/range/tuple/str,n) 随机抽取n个值
random.shuffle(list) 乱序,在原有基础上乱序
os 和操作系统交互
文件和文件夹的操作
    os.remove
    os.rename
    os.mkdir
    os.makedirs
    os.rmdir
    os.removedirs
    os.listdir
    os.stat 获取文件的信息
路径的操作
    os.path.join   目录的拼接
    os.path.split(path) # 将路径分割成两个部分,目录、文件/文件夹的名字
    os.path.dirname(path) # 返回这个path的上一级目录
    os.path.basename(path) # 文件/文件夹的名字
    os.path.exits  这个路径是否存在
    os.path.isfile 是否文件目录
    os.path.isdir  是否文件夹目录
    os.path.abspath 规范文件目录、返回一个绝对路径
    os.path.getsize
和python程序的工作目录相关的
    getcwd  # 获取当前的工作目录 get current working dir
    chdir   # 改变当前的工作目录 change dir
执行操作系统命令
    os.system(命令)
    os.popen(命令).read()

file文件中的一个内置变量,描述的是这个文件的绝对路径

sys 和python解释器
sys.argv 执行py文件的时候传入的参数
sys.path 查看模块搜索路径 import 模块的时候从这个路径下来寻找
sys.modules 查看当前导入的模块和它的命名空间
collections

from collections import Iterable
from collections import Iterator

from collections import OrderedDict
dd = OrderedDict([('a',1),('k1','v1')])  #创建有序字典  插入的时候默认在末尾,,默认有序

from collections import defaultdict #默认字典 { defaultdict(lambda : 默认值) }
d = defaultdict(可调用的) #d是一个默认字典 如果是list,可以直接append ,也可以和匿名函数结合使用

from collections import defaultdict

values = [11, 22, 33,44,55,66,77,88,99,90]

my_dict = defaultdict(list)

for value in  values:
    if value>66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)

hashlib模块

hashlib
登录验证 md5、sha - 动态加盐
文件的一致性校验 md5 - 不需要加盐

hashlib 摘要算法
多种算法
md5算法 :32位16进制的数字字符组成的字符串
应用最广大的摘要算法
效率高,相对不复杂,如果只是传统摘要不安全 #撞库
sha算法 :40位的16进制的数字字符组成的字符串
sha算法要比md5算法更复杂
且shan n的数字越大算法越复杂,耗时越久,结果越长,越安全

转化密文函数

def get_md5(a):
    import hashlib
    md5_obj = hashlib.md5()
    md5_obj.update(a.encode('utf-8'))
    return md5_obj.hexdigest()
import hashlib
def get_md5(a,b):
    md5_obj = hashlib.md5(a.encode('utf-8'))
    md5_obj.update(b.encode('utf-8'))
    ret = md5_obj.hexdigest()
    return ret

def login(file_name):
    while 1:
        inp_name = input('请输入你的用户名:').strip()
        if inp_name == '':continue
        while 1:
            inp_pwd = input('请输入你的密码:').strip()
            if inp_pwd == '':continue
            else:break
        with open(file_name,encoding='utf-8') as f:
            for line in f:
                name,pwd = line.strip().split('|')
                if name == inp_name and pwd == get_md5(inp_name,inp_pwd):
                    print('登录成功')
                    return True
            else:print('登录失败!')
login('hqs.txt')
import hashlib
md5_obj = hashlib.md5()
md5_obj.update('hello,world'.encode('utf-8'))
ret1 = md5_obj.hexdigest()
print(ret1)

md5_obj = hashlib.md5()
md5_obj.update('hello'.encode('utf-8'))
md5_obj.update(',world'.encode('utf-8'))
ret2 = md5_obj.hexdigest()
print(ret2)

# 结论:ret1 == ret2

文件的校验

# 一次性读取
import hashlib
def get_md5(file_name):
    with open(file_name,'rb') as f:
        md5_obj1 = hashlib.md5()
        md5_obj1.update(f.read())
    return md5_obj1.hexdigest()
#分段读取
import os
import hashlib
def get_file_md5(file_name,butter = 1024):
    md5_obj = hashlib.md5()
    file_size = os.path.getsize(file_name)
    with open(file_name,'rb') as f:
        while file_size:
            count = f.read(1024)
            md5_obj.update(count)
            file_size -= len(count)
        return md5_obj.hexdigest()
import hashlib
def get_file_md5(filename):
    md5_obj = hashlib.md5()
    with open(filename,'rb') as f:
        for line in f:
            md5_obj.update(line)
    return md5_obj.hexdigest()

configparser
处理配置文件的模块
1 开发环境
2 测试环境
3 生产环境

import configparser
config = configparser.ConfigParser()   #config相当于一个对象/字典
config["DEFAULT11111"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9',
                     'ForwardX11':'yes'
                     }
config['bitbucket.org'] = {'User':'hg'}
config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'}
with open('example.ini', 'w') as configfile:
   config.write(configfile)

logging 模块

logging
日志模块

import logging
logging.basicConfig(level=logging.INFO)
logging.debug('debug message')    # 计算或者工作的细节
logging.info('info message')      # 记录一些用户的增删改查的操作
logging.warning('input a string type') # 警告操作
logging.error('error message')     # 错误操作
logging.critical('critical message')  # 批判的 直接导致程序出错退出的
import logging
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%c',
                    filename='test.log')    #filename='test.log'  配置写入文件或者显示
logging.warning('input a string type') # 警告操作
logging.error('EOF ERROR ') # 警告操作
logging.info('小明买了三斤鱼') # 警告操作
import logging
# 先创建一个log对象 logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) #改变默认的INFO  是输入输出都是DEBUG以下
# 还要创建一个控制文件输入的文件操作符
fh = logging.FileHandler('mylog.log')
# 还要创建一个控制屏幕输出的屏幕操作符
sh = logging.StreamHandler()
# 要创建一个格式
fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fmt2 = logging.Formatter('%(asctime)s - %(name)s[line:%(lineno)d] - %(levelname)s - %(message)s')

# 文件操作符 绑定一个 格式
fh.setFormatter(fmt)
# 屏幕操作符 绑定一个 格式
sh.setFormatter(fmt2)
sh.setLevel(logging.WARNING)  #屏蔽掉WARNING上的屏幕输出
# logger对象来绑定:文件操作符, 屏幕操作符
logger.addHandler(sh)
logger.addHandler(fh)


logger.debug('debug message')    # 计算或者工作的细节
logger.info('info message')      # 记录一些用户的增删改查的操作
logger.warning('input a string type') # 警告操作
logger.error('error message')     # 错误操作
logger.critical('critical message')  # 批判的 直接导致程序出错退出的

logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过----fh.setLevel(logging.Debug)单对文件流设置某个级别

模块和包

模块
import

import

import一个模块相当于执行了这个模块

在import模块的时候发生的事情
1.寻找模块
2.如果找到了,就开辟一块儿空间,执行这个模块
3.把这个模块中用到的名字都收录到新开辟的空间中
4.创建一个变量来引用这个模块的空间

模块搜索路径
所以总结模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块
正常的sys.path中出了内置、扩展模块所在的路径之外
只有一个路径是永远不会出问题
你直接执行的这个文件所在的目录
一个模块是否能被导入,就看这个模块所在的目录在不在sys.path中

两种运行一个py文件的方式
直接运行它 : cmd python xx.py pycharm 脚本

__name__ == '__main__'

导入它 : 模块

__name__ == '模块名

from import
在from import的过程中发生了哪些事情
被导入的内容和本文件之间命名空间的关系
from import 多个内容
给导入的内容起别名
from ... import *

* 和 __all__

1.pyc文件、pyi文件
pyc只能提高程序的启动效率并不能提高程序的执行效率
2.模块的导入和修改
3.模块的循环引用 不能循环 只能单向
4.dir(模块名) dir(list) dir(str) iter
可以获取这个模块中的所有名字(列表你显示字符串,反射)


什么是包 package
含有一个init.py的文件夹就是一个包
包中通常含有一些py文件
从包中导入模块

import 包.包.模块
import 包.包.模块.属性/方法

1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

  1. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含init.py文件的目录)

  2. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的init.py,导入包本质就是在导入该文件

强调:

1. 在python3中,即使包下没有init.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

import os
os.makedirs('glance/api')
os.makedirs('glance/cmd')
os.makedirs('glance/db')
l = []
l.append(open('glance/__init__.py','w'))
l.append(open('glance/api/__init__.py','w'))
l.append(open('glance/api/policy.py','w'))
l.append(open('glance/api/versions.py','w'))
l.append(open('glance/cmd/__init__.py','w'))
l.append(open('glance/cmd/manage.py','w'))
l.append(open('glance/db/models.py','w'))
map(lambda f:f.close() ,l)

特别需要注意的是:可以用import导入内置或者第三方模块(已经在sys.path中),但是要绝对避免使用import来导入自定义包的子模块(没有在sys.path中),应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式

直接导入包
绝对导入

glance/                   

├── __init__.py      from glance import api
                             from glance import cmd
                             from glance import db

├── api                  

│   ├── __init__.py  from glance.api import policy
                              from glance.api import versions

│   ├── policy.py

│   └── versions.py

├── cmd                 

│   ├── __init__.py     from glance.cmd import manage

│   └── manage.py

└── db                   

    ├── __init__.py         from glance.db import models

    └── models.py

glance2.api.policy.get()
导入包的过程中发生了什么事?
相当于执行了这个包的 init.py文件
sys.path中的内容 永远是当前你执行的文件
['D:\骑士计划PYTHON1期\day26']

相对导入

glance/                   

├── __init__.py      from . import api  #.表示当前目录
                            from . import cmd
                            from . import db

├── api                  

│   ├── __init__.py  from . import policy
                             from . import versions

│   ├── policy.py

│   └── versions.py

├── cmd              

│   ├── __init__.py     from . import manage

│   └── manage.py    from ..api import policy   
                     #..表示上一级目录,想再manage中使用policy中的方法就需要回到上一级glance目录往下找api包,从api导入policy

└── db               from . import models

    ├── __init__.py

    └── models.py

运用了相对导入的文件不能被直接执行
'.'表示当前目录
'..'表示上一级目录
import glance3

glance/                   

├── __init__.py     from .api import *
                            from .cmd import *
                            from .db import *    
├── api                  

│   ├── __init__.py   __all__ = ['policy','versions'] 

│   ├── policy.py

│   └── versions.py

├── cmd               

│   ├── __init__.py      __all__ = ['manage']   

│   └── manage.py    

└── db                             

    ├── __init__.py         __all__ = ['models'] 

    └── models.py


import glance
policy.get()

上一篇下一篇

猜你喜欢

热点阅读