python之路---模块

  在python中,为了简少代码重复量,我们将引用了函数,面向对象 等方法。为了能够让这些函数,面向对象可以再其他python文件中引用,我们将功能函数写在一个py文件中,该py文件即是一个模块,可以共其他py文件引用。同时,我们将程序同类型的功能放进同一个py模块中,易读性和维护性也更换。总结一句,py文件即模块。

 

模块的导入

  import:

    1.执行对应文件

    2.引入变量名

  import会将导入的模块执行一遍,并引入变量名,将其内容存入内存中。

  import 模块 会从sys.path中找出模块文件,如果不在坏境变量的路径中,会提示报错。无法找到该模块。

  path路径添加:

  sys.path.append(新路径)

BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
print(sys.path)
添加执行文件上一层文件路径

 

 

各个模块介绍:

  time模块:

  三种时间表示

  在Python中,通常有这几种方式来表示时间:

  • 时间戳(timestamp): 通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
  • 格式化的时间字符串
  • 元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)

  

  三种时间格式的互相转换关系:

  

import time
#时间戳格式
print(time.time())

#结构化时间格式
print(time.localtime())    #将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
print(time.gmtime())        #和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。

#字符串时间
print(time.strftime("%Y-%m-%d %H:%M:%S"))  #结构化时间转换为字符串格式化时间
print(time.ctime(time.time()))      #将时间戳时间转换为固定的字符串时间格式
print(time.asctime(time.localtime()))  #将结构化时间转换为固定的字符串时间格式



#时间戳转换为结构化时间
time.localtime()  #东八区时间
time.gmtime()   #UTC时间

#把字符串时间转换为结构化时间
print(time.strptime('2017-05-27 20:11:23','%Y-%m-%d %X'))

#将结构化时间转换为时间戳
#time.mktime(time.localtime())
时间格式转换

 

  random模块

import random

print(random.random())    #float

print(random.randrange(1,4))  #int,在1,2,3中随机选取

print(random.randint(1,5))  #int,在1,2,3,4,5中随机选取

print(random.choice([1,'23',[4,5]]))   #在1,'23',[4,5]这三个项中随机选取

print(random.sample([1,'23',[4,5]],2))  #在1,'23',[4,5]这三个项中随机选取两个

print(random.uniform(1,3))#1.927109612082716 #[1,3)随机选取一个浮点数

l=[1,2,3,4]
print(random.shuffle(l))  #将原有列表顺序随机打乱 
print(l)

  OS模块

   os模块是与操作系统交互的一个接口

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息
os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  运行shell命令,直接显示
os.environ  获取系统环境变量
os.path.abspath(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.getatime(path)  返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
View Code

  sys模块

sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n)        退出程序,正常退出时exit(0)
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操作系统平台名称

  sys.argv 使用后,类似shell那样,可以再程序执行前将参数传入

import sys,time
for i in range(1,11):
    sys.stdout.write("\r%s%s"%(i,'#'*i))
    time.sleep(0.5)
    sys.stdout.flush()
进度条

  json模块

  json是不同语言间通用的一种标签语言,符号json格式的内容,可以再不同语言程序之间传输。

  JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

  

  所以,使用json,有两个作用:

  1.存取特殊类型的数据,例如字典,列表等。

  2.在不同语言程序间传输内容

  在使用json存放数据时,我们需要将数据序列化。

 那么什么是序列化:

  我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

  序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

  反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

import json
#--------------序列化---------------------
data={'a':1,'b':2,'c':3}
#--------------json,dumps------------
with open('text.log','w') as f:
    data_new=json.dumps(data)
    f.write(data_new)
#--------------json,dump------------
with open('text.log','a') as f:
    json.dump(data,f)  # 等于 f.write(json.dumps(data))


#-------------反序列化---------------------
#-----------------json.load-----------------
with open('text.log','r',encoding='utf8') as f:
    data=json.load(f)   #等于 json.loads(f.read())
#-----------------json.loads-----------------
with open('text.log','r',encoding='utf8') as f:
    data=f.read()
    data=json.loads(data)
print(data)

  注意点:

import json
#dct="{'1':111}"#json 不认单引号
#dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1}

dct='{"1":"111"}'
print(json.loads(dct))

#conclusion:
#        无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
View Code

 

  Pickle模块

  Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系

import pickle
#--------------序列化---------------------
data={'a':1,'b':2,'c':3}
# #--------------pickle.dumps------------
with open('text.log','wb') as f:  #pickle序列化后的数据类型是bytes,所以写入文档中需要使用二进制模式
    data_new=pickle.dumps(data)
    f.write(data_new)
--------------pickle.dump------------
with open('text.log','wb') as f:
    pickle.dump(data,f)  # 等于 f.write(json.pickle(data))


-------------反序列化---------------------
#-----------------pickle.load-----------------
with open('text.log','rb') as f:   #读取的数据类型为bytes,所以用二进制的方法读取
    data=pickle.load(f)   #等于 pickle.loads(f.read())
#-----------------pickle.loads-----------------
with open('text.log','rb') as f:  #读取的数据类型为bytes,所以用二进制的方法读取
    data=f.read()
    data=pickle.loads(data)
print(data)

 

   shelve模块

   shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型

import shelve

f = shelve.open('test.txt')

#-----------根据序列的形式进行赋值---------
f['test1']={'a':1,'b':2}
f['test2']=[1,2,3]   #shelve保存数据后,会生成test.txt.bak; test.txt.dat; test.txt.dir 三个文件

#-----------类似字典的形式查询数据
print(f.get('test1'))
print(f.get('test1')['a'])

 

   XML模块

  xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但是json使用更简单。XML诞生比较早,现在还有较多金融行业在使用。

import  xml.etree.ElementTree as ET

tree=ET.parse('test.xml')
root=tree.getroot()

#---------------------查--------------------------
print(root.tag)    #tag 查看标签名
for item in root:
    print(item.tag,item.attrib)   #attrib 查看属性
    for i in item:
        print(i.tag, i.text)      #text 查看标签间的内容

for item in root:                    #左边结果和下面的输出结果一致,下面的代码更优
    for node in item.iter('year'):  #for node in root.iter('year'):
        print(node.tag, node.text)    #    print(node.tag,node.text)



#---------------------修改-------------------------
for node in root.iter('year'):     #获取year标签
    new_year = int(node.text) + 1      #将原来的内容+1
    node.text = str(new_year)
    node.set("updated","yes")          #更新
    tree.write("test.xml")        #将更新后的树从内存中写入文件

#----------------------删除-------------------------------

for country in root.findall('country'):
    rank = int(country.find('rank').text)
    if rank > 50:
        root.remove(country)

tree.write('output.xml')

  自己创建xml文件

import xml.etree.ElementTree as ET

new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
age = ET.SubElement(name, "age", attrib={"checked": "no"})
sex = ET.SubElement(name, "sex")
sex.text = '33'
name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age = ET.SubElement(name2, "age")
age.text = '19'

et = ET.ElementTree(new_xml)  # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True)

ET.dump(new_xml)  # 打印生成的格式
View Code

 

 re模块

  re模块是Python关于正则表达式匹配的模块。常用方法有:re.findall().re.search,re.match(),re.split(),re.sub,re,subn等

import re

print(re.findall('new','this is new,so new'))   #以列表的形式,返回所有匹配到的内容
print(re.search('new','this is new,so new'))   #以对象的形式,返回第一个匹配到的内容,该对象可以通过group查看
print(re.match('new','this is new,so new'))    #返回None . match 匹配开头的内容,类似于字符串的startwwith。
print(re.match('new','new,so new'))             #以对象的形式,返回new
print(re.sub('old','new','this is old,so old'))  #将第一个匹配内容 替换为第二个,以字符串的形式返回内容.
print(re.subn('old','new','this is old,so old'))#将第一个匹配内容 替换为第二个,以元组的形式返回修改回的内容,及修改的个数
print(re.split(',','1,2,3,4,5'))  #根据定义的匹配内容,分割字符串,以列表的形式返回

new_re=re.compile('old')  #如果要大量处理一个同样的规则,可以将该规则使用compile封装进去,然后再后续时候该对象时,不需要再定义匹配规则
print(new_re.findall('this is old,so old'))
print(new_re.search('this is old ,so old'))

a=re.finditer('new','this is new,so new') #生成一个迭代器
print(next(a).group())    #返回一个对象,使用group查看内容

  注意点:

import re
#-------------------1--------------------------------------------- 
ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com')
print(ret)#['oldboy']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
 
ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com')
print(ret)#['www.oldboy.com']

#-----------------------2----------------------------------------------
可以 使用 (?P<name>)来定义组的名称。例如 
print(re.search(r'(?P<dig>\d+)','aa234bb345cc').groupdict())

 

   logging模块

   一.使用 logging.basicConfig 来进行日志操作

import logging

logging.basicConfig(
    level=logging.INFO,   #默认登记为warning
    filename='text.log',#如果没有该项配置,则输出在界面上。有的话则保存在设置的文档中。
    filemode='w',    #默认为追加模式。模式可更改
    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  #记录日志格式。

)

logging.debug('debug')   #等级为critical>error>warning>info>debug
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
View Code

format 各种格式说明:

  logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
  filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
  filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
  format:指定handler使用的日志显示格式。 
  datefmt:指定日期时间格式。 
  level:设置rootlogger(后边会讲解具体概念)的日志级别 
  stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename

      和stream两个参数,则stream参数会被忽略。


format参数中可能用到的格式化串:
  %(name)s Logger的名字
  %(levelno)s 数字形式的日志级别
  %(levelname)s 文本形式的日志级别
  %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
  %(filename)s 调用日志输出函数的模块的文件名
  %(module)s 调用日志输出函数的模块名
  %(funcName)s 调用日志输出函数的函数名
  %(lineno)d 调用日志输出函数的语句所在的代码行
  %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
  %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
  %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
  %(thread)d 线程ID。可能没有
  %(threadName)s 线程名。可能没有
  %(process)d 进程ID。可能没有
  %(message)s用户输出的消息

  二.logger对象

import logging

logger = logging.getLogger()    #logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger.
print(logger.name)   #查看logger的name.在这边,返回root
logger.setLevel(logging.INFO)   #设置该用户的输出级别

# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log')

# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setFormatter(formatter)
ch.setFormatter(formatter)

logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
logger.addHandler(ch)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')
'''
    logging库提供了多个组件:Logger、Handler、Filter、Formatter。
    Logger对象提供应用程序可直接使用的接口,
    Handler发送日志到适当的目的地,
    Filter提供了过滤日志信息的方法,
    Formatter指定日志显示格式。
'''

  2.   Logger是一个树形层级结构,输出信息之前都要获得一个Logger(如果没有显示的获取则自动创建并使用root Logger,如第一个例子所示)。如果设置了两个用户名一样的Logger,那么实际上就只是一个而已。

import logging
logger = logging.getLogger()            #设置root
logger1 = logging.getLogger('mysql')   #设置用于mysql为logger1
logger1.setLevel(logging.INFO)   #logger的输出级别为 INFO

logger2=logging.getLogger('mysql')  #设置用于mysql为logger2
logger2.setLevel(logging.WARNING)   #logger的输出级别为 WARNING

fh = logging.FileHandler('test.log')
ch = logging.StreamHandler()

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setFormatter(formatter)
ch.setFormatter(formatter)


logger.addHandler(ch)  #由于父层有设置流显示,所以当父层传递日志给子层,会打印一次
logger1.addHandler(fh)
logger1.addHandler(ch)  #子层打印一次
logger2.addHandler(fh)
logger2.addHandler(ch)

logger1.debug('logger debug message')
logger1.info('logger info message')
logger1.warning('logger warning message')
logger1.error('logger error message')
logger1.critical('logger critical message')

logger2.debug('logger debug message')
logger2.info('logger info message')
logger2.warning('logger warning message')
logger2.error('logger error message')
logger2.critical('logger critical message')
'''
1.
    logger1级别为info,应该输出内容为info及以上的共四个级别的日志 
    logger2级别为warning,应该输出内容为warning及以上的共三个级别的日志 
    但实际输出为六行内容,且都是warning 及以上级别日志
2.由于logger是 树形层级结构,既会将消息分发给他的handler进行处理也会传递给所有的祖先Logger处理。  
    
'''

   filter

import logging

logger = logging.getLogger()
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log')

# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setFormatter(formatter)
ch.setFormatter(formatter)

# 定义一个filter
filter = logging.Filter('mylogger')
fh.addFilter(filter)
ch.addFilter(filter)  # 这两行的作用 等于logger.addFilter(filter)

#logger.addFilter(filter)
logger.addHandler(fh)
logger.addHandler(ch)


logger.setLevel(logging.DEBUG)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

  

  configparser模块

  1.该模块用来做配置文件的操作,且配置文件的格式应该如下:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
  
[bitbucket.org]
User = hg
  
[topsecret.server.com]
Port = 50022
ForwardX11 = no

  2.生成一个文档

import configparser
  
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9'}
  
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'     # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:  #写入文件时调用config 的方法
   config.write(configfile)  
import configparser

config = configparser.ConfigParser()

#---------------------------------------------查
print(config.sections())   #[]

config.read('example.ini')

print(config.sections())   #['bitbucket.org', 'topsecret.server.com']

print('bytebong.com' in config)# False

print(config['bitbucket.org']['User']) # hg

print(config['DEFAULT']['Compression']) #yes

print(config['topsecret.server.com']['ForwardX11'])  #no


for key in config['bitbucket.org']:
    print(key)


# user
# serveraliveinterval
# compression
# compressionlevel
# forwardx11


print(config.options('bitbucket.org'))#['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
print(config.items('bitbucket.org'))  #[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')]

print(config.get('bitbucket.org','compression'))#yes


#---------------------------------------------删,改,增(config.write(open('i.cfg', "w")))


config.add_section('yuan')

config.remove_section('topsecret.server.com')
config.remove_option('bitbucket.org','user')

config.set('bitbucket.org','k1','11111')

config.write(open('i.cfg', "w"))
View Code

 

  加密模块

import hashlib,re
obj=hashlib.md5('admin'.encode('utf8'))  #加盐
obj.update('hello'.encode('utf8'))
print(obj.hexdigest())


import hmac
h = hmac.new('alvin'.encode('utf8'))
h.update('hello'.encode('utf8'))
print (h.hexdigest())#320df9832eab4c038b6c1d7ed73a5940

 

posted @ 2017-05-31 16:52  小聪傻大  阅读(241)  评论(0编辑  收藏  举报