python常用模块
1、time
2、datetime
3、random
4、os
5、sys
6、pickle & json
7、logging
8、shutil
9、zipfile
10、shelve
11、xml
12、PyYaml
13、configparser
14、hashlib
15、subprocess
16、re
time
# 当前时间戳 time.time() # 和标准时间(格林威治时间)的偏差 time.altzone # 返回时间格式 Sat Feb 18 15:11:10 2017 time.asctime() # 返回时间格式 Sat Feb 18 15:11:10 2017 time.ctime() # 返回本地时间对象 time.localtime() t = time.localtime() print(t.tm_year,t.tm_mon) t = time.localtime(time.time()-(60*60*24)) # 返回UTC时间(格林威治时间)对象 time.gmtime() time.strftime("%Y-%m-%d %H:%M:%S") 2017-02-18 15:24:25 # 显示十天前的时间 struct_time = time.localtime(time.time() - 86400) time.strftime("%Y-%m-%d %H:%M:%S", struct_time) s_time = time.strptime("2017-02-17", "%Y-%d-%m") time.mktime(s_time) time.strptime() time.mktime() "2016/05/22" ----------------> 时间对象 --------------> 时间戳
datetime
# 返回结果 2017-18 15:24:25 datetime.datetime.now() # 时间戳直接转成日期格式 datetime.datetime.fromtimestamp(time.time()) datetime.datetime.now() - datetime.timedelta(hours=3,minutes=20) # 时间替换 datetime.datetime.now().replace(year=2016,month=3)
random
print(random.randint(1,10)) print(random.randrange(1,10)) 不包含10,可以加步长 print(random.sample([1,2,3,4,5],2)) 随机取两个元素列表 -------------------------------------------------------------------- 随机验证码 第一种 import random checkcode='' for i in range(4): current = random.randrange(0,4) if current != i: temp = chr(random.randint(65,90)) else: temp = random.randint(0,9) checkcode += str(temp) print(checkcode) 第二种 import random,string source = string.digits + string.ascii_lowercase print("".join(random.sample(source,6)))
os
import platform print(platform.system()) 显示当前操作系统 os.popen('pwd').read() 可以拿到命令的执行结果 os.system 只返回命令执行结果的状态
sys
sys.argv
sys.path
pickle & json
account = { 'id': 62253454873, 'credit': 15000, 'balance': 8000, 'expire_date':'2020-05-21', 'password': 'fdsjkl' } f = open('account.db','w') f.write(str(account)) f.close() ------------------------------ f = open('account.db','r') account = eval(f.readlines()) 序列化 内存 --> 字符串 反序列化 字符串 --> 内存 pickle.dumps、pickle.dump 序列化 pickle.loads、pickle.load 反序列化 json 只支持str, int, float, set, dict, list, tuple数据类型
logging
logging日志可以分为debug(),info(),warning(),error(),critical()5个级别
简单用法
>>> import logging >>> logging.warning("user [alex] attempted wrong password more than 3 times") WARNING:root:user [alex] attempted wrong password more than 3 times >>> logging.critical("server is down") CRITICAL:root:server is down
将日志写入文件
import logging # 将日志级别设置为INFO,大于等于INFO级别的日志会写入文件中 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')
日志格式
|
%(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 |
用户输出的消息 |
Python 使用logging模块记录日志涉及四个主要类
logger提供了应用程序可以直接使用的接口;
handler将(logger创建的)日志记录发送到合适的目的输出;
filter提供了细度设备来决定输出哪条日志记录;
formatter决定日志记录的最终输出格式。
logger
每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
LOG=logging.getLogger(”chat.gui”)
而核心模块可以这样:
LOG=logging.getLogger(”chat.kernel”)
Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别
handler
handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
1) logging.StreamHandler
使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
StreamHandler([strm])
其中strm参数是一个文件对象。默认是sys.stderr
2) logging.FileHandler
和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
FileHandler(filename[,mode])
filename是文件名,必须指定一个文件名。
mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。
3) logging.handlers.RotatingFileHandler
这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
4) logging.handlers.TimedRotatingFileHandler
这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨
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')
文件自动截断例子
import logging from logging import handlers logger = logging.getLogger(__name__) log_file = "timelog.log" #fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3) fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3) formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) logger.warning("test1") logger.warning("test12") logger.warning("test13") logger.warning("test14")
shutil
# 高级的文件、文件夹、压缩包处理模块 shutil.copyfileobj(原文件,目标文件,每次读多少) shutil.copyfileobj(fsrc,fdst[,length]) # 拷贝文件 f = open("transactions.log") f2 = open("new.log", 'w') shutil.copyfileobj(f, f2) # 拷贝文件,不用读 shutil.copyfile("transactions.log", 'new_1.log') # 仅拷贝权限 shutil.copymode("transactions.log", 'new_1.log') # 拷贝状态信息 shutil.copystat("transactions.log", 'new_1.log') # 拷贝文件和权限 shutil.copy() # 拷贝文件和状态信息 shutil.copy2() # 递归的去拷贝文件,过滤 shutil.copytree("C:/Users\wescker\PycharmProjects\S16\Day05", "C:/Users\wescker\PycharmProjects\S16\Test", ignore=shutil.ignore_patterns('atm', '*.log')) # 递归删除文件 shutil.rmtree("C:/Users\wescker\PycharmProjects\S16\Test") # 递归去移动文件 shutil.move() # 创建压缩包并返回文件路径 shutil.make_archive("Day05", 'zip', "C:/Users\wescker\PycharmProjects\S16\Day05")
zipfile
# 压缩文件 z = zipfile.ZipFile('Day06.zip', 'w') z.write('new.log') z.write('transactions.log') z.write("C:/Users\wescker\PycharmProjects\S16\Day05/atm/atm/log/access.log") z.close() # 解压文件 z = zipfile.ZipFile("Day06.zip", 'r') z.extract('new.log') z.extractall("D:/") z.close()
shelve
import shelve d = shelve.open("shelve_test") class Test(object): def __init__(self, n): self.n = n def func(): print("haha") t = Test(123) t2 = Test(123334) name = ['alex', 'rain', 'test'] d['test'] = name d['t1'] = t d["t2"] = t2 d.close()
xml
xml的格式如下
<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
解析xml
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #遍历xml文档 for child in root: print(child.tag, child.attrib) for i in child: print(i.tag,i.text) #只遍历year 节点 for node in root.iter('year'): print(node.tag,node.text)
修改和删除xml文档内容
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() #修改 for node in root.iter('year'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated","yes") tree.write("xmltest.xml") #删除node 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) #打印生成的格式
PyYAML
参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation
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 >>> 'bytebong.com' in config False >>> config['bitbucket.org']['User'] 'hg' >>> config['DEFAULT']['Compression'] 'yes' >>> topsecret = config['topsecret.server.com'] >>> topsecret['ForwardX11'] 'no' >>> topsecret['Port'] '50022' >>> for key in config['bitbucket.org']: print(key) ... user compressionlevel serveraliveinterval compression forwardx11 >>> config['bitbucket.org']['ForwardX11'] 'yes'
增删改查语法
[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"))
hashlib
用于加密相关的操作,可用作文件传输校验,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib m = hashlib.md5() m.update(b"Hello") m.update(b"It's me") print(m.digest()) m.update(b"It's been a long time since last time we ...") print(m.digest()) #2进制格式hash print(len(m.hexdigest())) #16进制格式hash ''' def digest(self, *args, **kwargs): # real signature unknown """ Return the digest value as a string of binary data. """ pass def hexdigest(self, *args, **kwargs): # real signature unknown """ Return the digest value as a string of hexadecimal digits. """ pass ''' 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())
subprocess
从课上讲解来看,subprocess主要是执行shell命令,获取正常输出,错误输出,返回值
res = subprocess.Popen('pwd;echo $TEST',env={'TEST':'abc123'},preexec_fn=sayhi,cwd="/tmp",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> res.stdout.read() >>> b'sayhi\n/tmp\nabc123\n' # 返回执行状态和执行结果,以元组形式返回 a = subprocess.getoutput('ls -l') >>> res = subprocess.Popen('df -h|grep /dev/sda1',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> res.stdout.read() b'/dev/sda1 291M 39M 238M 14% /boot\n' >>> res.stderr.read() b'' >>> res.poll() 0
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' '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c '\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' '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
最常用的匹配语法
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换
浙公网安备 33010602011771号