关闭

python(五)常用模块学习

标签: python模块正则表达式
2065人阅读 评论(0) 收藏 举报
分类:

目录

模块介绍
模块的分类
常用内置模块
time &datetime模块
random
os
sys
shutil
json & picle
shelve
xml处理
yaml处理
configparser
hashlib
subprocess
logging模块
re正则表达式

一、模块介绍

1. 定义:

模块:本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test)
用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能)

2. 语法:

  • import 语句

当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。搜索路径是一个解释器会先进行搜索的所有目录的列表。
导入模块:

import module1[, module2[,... moduleN]

调用符号:.

import os
print(os.sep)
print(os.getcwd())
  • From…import 语句

Python的from语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:

from modname import name1[, name2[, ... nameN]]

From…import* 语句
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

from modname import *

这提供了一个简单的方法来导入一个模块中的所有项目。慎用 from…import *。

  • import 和 from 的区别:

import导入使用时,加前缀 module.func()。相当于把模块代码放在当前文件中执行一遍。
from可以指定需要的函数或变量导入。
导入模块和当前py文件都有同一个函数,调用会调用哪一个?
因为python是解释型,所以后面覆盖前面。

  • from … import … as …

3. import本质

  • import 本质:
    导入一个模块本质就是解释执行一个python文件
    导入一个包本质就是解释该包下的__init__.py文件
module = all_code(所有代码)
import :本质把模块所有代码解释一遍,复制给模块名
from module import name :把这个模块的代码把哪一部分给解释了,赋值给name
  • __init__.py

:本质就是一个目录(必须带有一个__init__.py文件),用来从逻辑上组织模块
导入包,怎么导入?
导入包的本质:执行包下面的__init__.py文件

导入包下的模块
包下面的模块,这样调用是错误的

import package
package.module.test()  # 这样调用是不行的。

在__init__.py内容中导入模块

from . import module
# "."指的相对路径,指的谁的相对路径?__init__.py的相对路径还是调用init的那个模块的?
指的是__init__.py的相对路径。

4、路径搜索和搜索路径

上面提到的都是导入同级目录下的模块,如果不在同一个目录下:
import module_name实际找module_name.py文件,是文件就一定要有路径。
导入模块就是:找到.py文件的位置,把它执行一遍,从哪里找呢?sys.path.

>>> import sys
>>> sys.path
['', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35\\python35.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35\\lib\\site-packages']
# 以上可见:sys.path 是一个列表,
# 里面的 '' 指的当前路径,这是为何查找模块先从当前目录查找的原因
os.path.abspath(__file__)  # 当前文件绝对路径
os.path.dirname(os.path.abspath(__file__))  #获取目录名
sys.path.append() :追加到最后
# 所以:可以如下,动态添加路径到第一位
sys.path.insert 

5. 导入优化

import module_test
# import导入情况,如果重复调用,python就会重复找,避免重复找,可以用from方式导入
from module_test import test

6. 阻止属性导入

如果你不想让某个模块属性被 “from module import *” 导入 , 那么你可以给你不想导入的属性名称加上一个下划线( _ )。 不过如果你导入了整个模块或是你显式地导入某个属性这个隐藏数据的方法就不起作用了。

二、模块的分类

a:标准库
b:开源模块-第三方模块
c:自定义模块

三、常用内置模块

1、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    输出用于分割文件路径的字符串
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  运行shell命令,直接显示
os.environ  获取系统环境变量
os.path.abspath(path)  返回path规范化的绝对路径
os.path.split(path)  将path分割成目录和文件名二元组返回,它仅仅是以 "PATH" 中最后一个 '/' 作为分隔符,分隔后,将索引为0的视为目录(路径),将索引为1的视为文件名
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所指向的文件或者目录的最后修改时间

2、time和datetime
在Python中,通常有这几种方式来表示时间:

  1. 时间戳
  2. 格式化的时间字符串
  3. 元组(struct_time)共九个元素。

由于Python的time模块实现主要调用C库,所以各个平台可能有所不同。
 
UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8。DST(Daylight Saving Time)即夏令时。
 
时间戳(timestamp)的方式:通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。返回时间戳方式的函数主要有time(),clock()等。
 
元组(struct_time)方式:struct_time元组共有9个元素,返回struct_time的函数主要有gmtime(),localtime(),strptime()。

time.time()  # 获取时间戳:当前时间减1970-1-1 00:00 ==> 秒
>>> time.localtime()  # 本地时间,元组方式(tm_isdst() 是否夏令时)
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=29, tm_hour=0, tm_min=51, tm_sec=37, tm_wday=0, tm_yday=242, tm_isdst=0) 

help(time)  # 模块帮助
>>> time.timezone  # 查看时区
-28800  # 28800/60秒/60分 = 8时 ==> utc --> 标准+8 

time.sleep()  # 时间睡几秒
time.gmtime()   # 不加时间戳,为国际标准时间
time.localtime()   # 不加时间戳,本地时间
# 加上则从1970年开始算。
  • 时间转为时间戳
>>> x = time.localtime()
>>> x
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=29, tm_hour=1, tm_min=0, tm_sec=8, tm_wday=0, tm_yday=242, tm_isdst=0)
>>> time.mktime(x)
1472403608.0  
  • 格式化时间字符串
>>> time.strftime("%Y-%m-%d %X",x)
'2016-08-29 01:00:08'
>>> time.strptime('2016-08-29 01:00:08',"%Y-%m-%d %X")
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=29, tm_hour=1, tm_min=0, tm_sec=8, tm_wday=0, tm_yday=242, tm_isdst=-1)

strftime('格式',struct_time)  --> "格式化字符串"
strptime("格式化字符串","格式") --> "struct_time"
  • 转化时间戳和元组到时间字符串
>>> time.asctime(time.localtime())  # tuple -> string
'Mon Aug 29 01:10:47 2016' 
>>> time.ctime(888888888)  # seconds -> string
'Tue Mar  3 09:34:48 1998' 

这里写图片描述

  • 时间加减
import datetime

datetime.datetime.now() # 返回 2016-08-19 12:47:03.941925
datetime.date.fromtimestamp(time.time())  # 时间戳直接转成日期格式 2016-08-19

datetime.datetime.now() + datetime.timedelta(3) # 当前时间+3天
datetime.datetime.now() + datetime.timedelta(-3) # 当前时间-3天
datetime.datetime.now() + datetime.timedelta(hours=3) # 当前时间+3小时
datetime.datetime.now() + datetime.timedelta(minutes=30) # 当前时间+30分

3、random模块

random.random()  # 0~1之间的随机数
random.randint(1,3)  # [1,2,3]
random.randrange(3)  # [0,1,2]

random.choice('hello')  # 传入序列随机字母
random.sample('hello',2)  # 随机两个字母
random.uniform(1,3)  # 1~3直接随机
a = [1,2,3,4,5]
random.shuffle(a)  # 洗牌,打乱

import string
"".join(random.sample(string.hexdigits,4))  # 随机4位验证码

4、sys模块

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

5、shutil模块

高级的 文件、文件夹、拷贝、压缩包等 处理模块

shutil.copy 拷贝文件和权限
shutil.copytree(src,dst) 目录拷贝
shutil.move(src, dst)
shutil.rmtree
shutil.make_archive('')  压缩包
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的

6、ConfigParser

用于对特定的配置进行操作,当前模块的名称在 python 3.x 版本中变更为 configparser。
来看一个好多软件的常见文档格式如下

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes

[bitbucket.org]
User = hg

[topsecret.server.com]
Port = 50022
ForwardX11 = no

如果想用python生成一个这样的文档怎么做呢?

  • 生成
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.write(configfile)
  • 读取出来
>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read('example.ini')
['example.ini']
>>> config.sections()
['bitbucket.org', 'topsecret.server.com']
>>> 'bitbucket.org' in config
True
>>> config['bitbucket.org']['User']
'hg'
>>> config['DEFAULT']['Compression']
'yes'
>>> topsecret = config['topsecret.server.com']
>>> topsecret['ForwardX11']
'no'
>>> for key in config['bitbucket.org']: print(key)
...
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config['bitbucket.org']['ForwardX11']
'yes'
  • configparser增删改查语法
[section1]
k1 = v1
k2:v2

[section2]
k1 = v1

import ConfigParser

config = ConfigParser.ConfigParser()
config.read('i.cfg')

########## 读 ##########
#secs = config.sections()
#print secs
#options = config.options('group2')
#print options

#item_list = config.items('group2')
#print item_list

#val = config.get('group1','key')
#val = config.getint('group1','key')

########## 改写 ##########
#sec = config.remove_section('group1')
#config.write(open('i.cfg', "w"))

#sec = config.has_section('wupeiqi')
#sec = config.add_section('wupeiqi')
#config.write(open('i.cfg', "w"))


#config.set('group2','k1',11111)
#config.write(open('i.cfg', "w"))

#config.remove_option('group2','age')
#config.write(open('i.cfg', "w"))

7、hashlib模块  

用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法,hash 加密都是bytes类型

import hashlib

m = hashlib.md5()
m.update(b"Hello")
m.update(b"It's me")  # 更新字符串为“HelloIt's me”

print(m.digest()) #2进制格式hash
print(m.hexdigest()) #16进制格式hash
import hashlib

# ######## md5 ########

hash = hashlib.md5()
hash.update('admin')
print(hash.hexdigest())

# ######## sha1 ########
hash = hashlib.sha1()
hash.update('admin')
print(hash.hexdigest())

# ######## sha256 ########
hash = hashlib.sha256()
hash.update('admin')
print(hash.hexdigest())

# ######## sha384 ########
hash = hashlib.sha384()
hash.update('admin')
print(hash.hexdigest())

# ######## sha512 ########
hash = hashlib.sha512()
hash.update('admin')
print(hash.hexdigest())

python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密

import hmac
h = hmac.new('wueiqi')
h.update('hellowo')
print h.hexdigest()

8、Subprocess模块

调用subprocess.run(…)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:

p = subprocess.Popen("find / -size +1000000 -exec ls -shl {} \;",shell=True,stdout=subprocess.PIPE)
print(p.stdout.read())

可用参数:

  • args:shell命令,可以是字符串或者序列类型(如:list,元组)
  • bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
  • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
  • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
  • close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
    所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
  • shell:同上
  • cwd:用于设置子进程的当前目录
  • env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
  • universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
  • startupinfo与createionflags只在windows下有效
    将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

终端输入的命令分为两种:

  • 输入即可得到输出,如:ifconfig
  • 输入进行某环境,依赖再输入,如:python

需要交互的命令示例

import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write('print 1 \n ')
obj.stdin.write('print 2 \n ')
obj.stdin.write('print 3 \n ')
obj.stdin.write('print 4 \n ')

out_error_list = obj.communicate(timeout=10)
print out_error_list

9、re-正则表达式模块

常用正则表达式符号

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配
'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符结尾,同'$'
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
'\s'    匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'

最常用的匹配语法

re.match('匹配模式',"字符串")  # 从头开始匹配
re.search('匹配模式',"字符串")  # 匹配包含,匹配一次
re.findall('匹配模式',"字符串")  # 把所有匹配到的字符放到以列表中的元素返回

re.splitall  # 以匹配到的字符当做列表分隔符
p = re.compile(r'\d+')  # 以数字作为分隔符
print p.split('one1two2three3four4')  # 分割字符串
re.sub('格式','替换为','字符串','次数')  # 匹配字符并替换

分组匹配 和 group()、groups()、groupdict()

s = 'abc (72.5%) 123'
# 简单使用:result.group() 返回匹配值
>>> re.search('\w+\s',s).group()
'abc '
# 上面看不出分组匹配的力量,匹配出多个想要的值。用“()”括起来
>>> result = re.search('(\w+)\s\((.*)\)\s(\w+)',s)
>>> result.group()  # 即:result.group(0)
'abc (72.5%) 123'
>>> result.group(1)
'abc'
>>> result.group(2)
'72.5%'
>>> result.group(3)
'123'
# .groups()  # 结果返回'tuple'
>>> result.groups()
('abc', '72.5%', '123')
# .groupdict()  # 结果返回'dict'
>>> num = "371481199306143242"
>>> res = re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})", num)
>>> res.groupdict()
{'province': '3714', 'birthday': '1993', 'city': '81'}

10、logging模块

python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical() 5个级别,下面我们看一下怎么用。
最简单用法

import logging

logging.warning("user [alex] attempted wrong password more than 3 times")
logging.critical("server is down")

#输出
WARNING:root:user [alex] attempted wrong password more than 3 times
CRITICAL:root:server is down

看一下这几个日志级别分别代表什么意思

Level When it’s used
DEBUG Detailed information, typically of interest only when diagnosing problems.
INFO Confirmation that things are working as expected.
WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.
ERROR Due to a more serious problem, the software has not been able to perform some function.
CRITICAL A serious error, indicating that the program itself may be unable to continue running.

如果想把日志写到文件里,也很简单

import logging

logging.basicConfig(filename='example.log',level=logging.INFO)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。

logging.basicConfig(filename='example.log',level=logging.INFO)

感觉上面的日志格式忘记加上时间啦,日志不知道时间怎么行呢,下面就来加上!

import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')

#输出
12/12/2010 11:46:36 AM is when this event was logged.

如果想同时把log打印在屏幕和文件日志里,就需要了解一点复杂的知识 了

import logging

#create logger
logger = logging.getLogger('TEST-LOG')
logger.setLevel(logging.DEBUG)


# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create file handler and set level to warning
fh = logging.FileHandler("access.log")
fh.setLevel(logging.WARNING)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch and fh
ch.setFormatter(formatter)
fh.setFormatter(formatter)

# add ch and fh to logger
logger.addHandler(ch)
logger.addHandler(fh)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

11、json和pickle数据序列化

str eval
数据序列化

import json
json.dumps(info_)
json.loads(f.read())

json只能处理简单的,所有语言通用的,函数不能json序列化

import pickle

data = pickle.load(f)  # 等于以下
data = pickle.loads(f.read())

pickle可以序列化python所有的数据类型

12、shelve 模块

shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

import shelve

d = shelve.open('shelve_test') #打开一个文件

class Test(object):
    def __init__(self,n):
        self.n = n


t = Test(123) 
t2 = Test(123334)

name = ["alex","rain","test"]
d["test"] = name #持久化列表
d["t1"] = t      #持久化类
d["t2"] = t2

d.close()

转载请务必保留此出处:http://blog.csdn.net/fgf00/article/details/52357477

13、xml处理模块

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,json之前的交换方式
参考文档:http://www.cnblogs.com/alex3714/articles/5161349.html

14、PyYAML模块

Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:215544次
    • 积分:2434
    • 等级:
    • 排名:第16755名
    • 原创:82篇
    • 转载:4篇
    • 译文:0篇
    • 评论:17条
    最新评论