OS 模块
#getcwd() 获取当前工作目录(当前工作目录默认都是当前文件所在的文件夹) result = os.getcwd() print(result) #chdir()改变当前工作目录 os.chdir('/home/sy') result = os.getcwd() print(result) open('02.txt','w') #操作时如果书写完整的路径则不需要考虑默认工作目录的问题,按照实际书写路径操作 open('/home/sy/下载/02.txt','w') #listdir() 获取指定文件夹中所有内容的名称列表 result = os.listdir('/home/sy') print(result) #mkdir() 创建文件夹 #os.mkdir('girls') #os.mkdir('boys',0o777) #makedirs() 递归创建文件夹 #os.makedirs('/home/sy/a/b/c/d') #rmdir() 删除空目录 #os.rmdir('girls') #removedirs 递归删除文件夹 必须都是空目录 #os.removedirs('/home/sy/a/b/c/d') #rename() 文件或文件夹重命名 #os.rename('/home/sy/a','/home/sy/alibaba' #os.rename('02.txt','002.txt') #stat() 获取文件或者文件夹的信息 #result = os.stat('/home/sy/PycharmProject/Python3/10.27/01.py) #print(result) #system() 执行系统命令(危险函数) #result = os.system('ls -al') #获取隐藏文件 #print(result) #环境变量 ''' 环境变量就是一些命令的集合 操作系统的环境变量就是操作系统在执行系统命令时搜索命令的目录的集合 ''' #getenv() 获取系统的环境变量 result = os.getenv('PATH') print(result.split(':')) #putenv() 将一个目录添加到环境变量中(临时增加仅对当前脚本有效) #os.putenv('PATH','/home/sy/下载') #os.system('syls') #exit() 退出终端的命令 #os模块中的常用值 #curdir 表示当前文件夹 .表示当前文件夹 一般情况下可以省略 print(os.curdir) #pardir 表示上一层文件夹 ..表示上一层文件夹 不可省略! print(os.pardir) #os.mkdir('../../../man')#相对路径 从当前目录开始查找 #os.mkdir('/home/sy/man1')#绝对路径 从根目录开始查找 #name 获取代表操作系统的名称字符串 print(os.name) #posix -> linux或者unix系统 nt -> window系统 #sep 获取系统路径间隔符号 window ->\ linux ->/ print(os.sep) #extsep 获取文件名称和后缀之间的间隔符号 window & linux -> . print(os.extsep) #linesep 获取操作系统的换行符号 window -> \r\n linux/unix -> \n print(repr(os.linesep)) #导入os模块 import os #以下内容都是os.path子模块中的内容 #abspath() 将相对路径转化为绝对路径 path = './boys'#相对 result = os.path.abspath(path) print(result) #dirname() 获取完整路径当中的目录部分 & basename()获取完整路径当中的主体部分 path = '/home/sy/boys' result = os.path.dirname(path) print(result) result = os.path.basename(path) print(result) #split() 将一个完整的路径切割成目录部分和主体部分 path = '/home/sy/boys' result = os.path.split(path) print(result) #join() 将2个路径合并成一个 var1 = '/home/sy' var2 = '000.py' result = os.path.join(var1,var2) print(result) #splitext() 将一个路径切割成文件后缀和其他两个部分,主要用于获取文件的后缀 path = '/home/sy/000.py' result = os.path.splitext(path) print(result) #getsize() 获取文件的大小 #path = '/home/sy/000.py' #result = os.path.getsize(path) #print(result) #isfile() 检测是否是文件 path = '/home/sy/000.py' result = os.path.isfile(path) print(result) #isdir() 检测是否是文件夹 result = os.path.isdir(path) print(result) #islink() 检测是否是链接 path = '/initrd.img.old' result = os.path.islink(path) print(result) #getctime() 获取文件的创建时间 get create time #getmtime() 获取文件的修改时间 get modify time #getatime() 获取文件的访问时间 get active time import time filepath = '/home/sy/下载/chls' result = os.path.getctime(filepath) print(time.ctime(result)) result = os.path.getmtime(filepath) print(time.ctime(result)) result = os.path.getatime(filepath) print(time.ctime(result)) #exists() 检测某个路径是否真实存在 filepath = '/home/sy/下载/chls' result = os.path.exists(filepath) print(result) #isabs() 检测一个路径是否是绝对路径 path = '/boys' result = os.path.isabs(path) print(result) #samefile() 检测2个路径是否是同一个文件 path1 = '/home/sy/下载/001' path2 = '../../../下载/001' result = os.path.samefile(path1,path2) print(result) #os.environ 用于获取和设置系统环境变量的内置值 import os #获取系统环境变量 getenv() 效果 print(os.environ['PATH']) #设置系统环境变量 putenv() os.environ['PATH'] += ':/home/sy/下载' os.system('chls') os 常用方法 os.remove('path/filename’) 删除文件 os.rename(oldname, newname) 重命名文件 os.walk() 生成目录树下的所有文件名 os.chdir('dirname') 改变目录 os.mkdir/makedirs('dirname')创建目录/多层目录 os.rmdir/removedirs('dirname') 删除目录/多层目录 os.listdir('dirname') 列出指定目录的文件 os.getcwd() 取得当前工作目录 os.chmod() 改变目录权限 os.path.basename('path/filename’) 去掉目录路径,返回文件名 os.path.dirname('path/filename’) 去掉文件名,返回目录路径 os.path.join(path1[,path2[,...]]) 将分离的各部分组合成一个路径名 os.path.split('path') 返回( dirname(), basename())元组 os.path.splitext() 返回 (filename, extension) 元组 os.path.getatime\ctime\mtime 分别返回最近访问、创建、修改时间 os.path.getsize() 返回文件大小 os.path.exists() 是否存在 os.path.isabs() 是否为绝对路径 os.path.isdir() 是否为目录 os.path.isfile() 是否为文件
sys.argv 命令行参数List,第一个元素是程序本身路径 sys.modules.keys() 返回所有已经导入的模块列表 sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息 sys.exit(n) 退出程序,正常退出时exit(0) sys.hexversion 获取Python解释程序的版本值,16进制格式如:0x020403F0 sys.version 获取Python解释程序的版本信息 sys.maxint 最大的Int值 sys.maxunicode 最大的Unicode值 sys.modules 返回系统导入的模块字段,key是模块名,value是模块 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称 sys.stdout 标准输出 sys.stdin 标准输入 sys.stderr 错误输出 sys.exc_clear() 用来清除当前线程所出现的当前的或最近的错误信息 sys.exec_prefix 返回平台独立的python文件安装的位置 sys.byteorder 本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little' sys.copyright 记录python版权相关的东西 sys.api_version 解释器的C的API版本
sys.stdin,sys.stdout,sys.stderr
stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们
我们常用print和raw_input来进行输入和打印,那么 print 和 raw_input是如何与标准输入/输出流建立关系的呢?
其实Python程序的标准输入/输出/出错流定义在sys模块中,分别 为: sys.stdin,sys.stdout, sys.stderr 下列的程序也可以用来输入和输出是一样的: import sys
sys.stdout.write('HelloWorld!')
print 'Please enter yourname:',
name=sys.stdin.readline()[:-1]
print 'Hi, %s!' % name
那么sys.stdin, sys.stdout, stderr到底是什么呢?我们在Python运行环境中输入以下代码: import sys
for f in (sys.stdin,sys.stdout, sys.stderr): print f
输出为:
<open file'<stdin>', mode 'r' at 892210>
<open file'<stdout>', mode 'w' at 892270>
<open file'<stderr>', mode 'w at 8922d0>
由此可以看出stdin, stdout, stderr在Python中无非都是文件属性的对象,他们在Python启动时自动与Shell 环境中的标准输入,输出,出错关联。 而Python程序的在Shell中的I/O重定向与本文开始时举的DOS命令的重定向完全相同,其实这种重定向是由Shell来提供的,与Python 本身并无关系。那么我们是否可以在Python程序内部将stdin,stdout,stderr读写操作重定向到一个内部对象呢?答案是肯定的。 Python提供了一个StringIO模块来完成这个设想,比如: from StringIO import StringIO import sys buff =StringIO() temp =sys.stdout #保存标准I/O流 sys.stdout =buff #将标准I/O流重定向到buff对象 print 42, 'hello', 0.001 sys.stdout=temp #恢复标准I/O流 print buff.getvalue()
time模块
time模块中时间表现的格式主要有三种: a、timestamp时间戳,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量 b、struct_time时间元组,共有九个元素组。 c、format time 格式化时间,已格式化的结构使时间更具可读性。包括自定义格式和固定格式。 1、时间格式转换图:
2、主要time生成方法和time格式转换方法实例: #! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import time # 生成timestamp time.time() # 1477471508.05 #生成struct_time
# timestamp to struct_time 本地时间
time.localtime()
time.localtime(time.time())
# time.struct_time(tm_year=2016, tm_mon=10, tm_mday=26, tm_hour=16, tm_min=45, tm_sec=8, tm_wday=2, tm_yday=300, tm_isdst=0) # timestamp to struct_time 格林威治时间 time.gmtime() time.gmtime(time.time()) # time.struct_time(tm_year=2016, tm_mon=10, tm_mday=26, tm_hour=8, tm_min=45, tm_sec=8, tm_wday=2, tm_yday=300, tm_isdst=0) #format_time to struct_time time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X') # time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1) #生成format_time #struct_time to format_time time.strftime("%Y-%m-%d %X") time.strftime("%Y-%m-%d %X",time.localtime()) # 2016-10-26 16:48:41 #生成固定格式的时间表示格式 time.asctime(time.localtime()) time.ctime(time.time()) # Wed Oct 26 16:45:08 2016
struct_time元组元素结构 属性 值
tm_year(年) 比如2011
tm_mon(月) 1 - 12
tm_mday(日) 1 - 31 tm_hour(时) 0 - 23 tm_min(分) 0 - 59 tm_sec(秒) 0 - 61 tm_wday(weekday) 0 - 6(0表示周日) tm_yday(一年中的第几天) 1 - 366 tm_isdst(是否是夏令时) 默认为-1
format time结构化表示
常见结构化时间组合: print time.strftime("%Y-%m-%d %X")
#2016-10-26 20:50:13
3、time加减 #timestamp加减单位以秒为单位
import time
t1 = time.time()
t2=t1+10
print time.ctime(t1)#Wed Oct 26 21:15:30 2016 print time.ctime(t2)#Wed Oct 26 21:15:40 2016
datetime模块datatime模块重新封装了time模块,提供更多接口,提供的类有:date,time,datetime,timedelta,tzinfo。 1、date类 datetime.date(year, month, day) 静态方法和字段 date.max、date.min:date对象所能表示的最大、最小日期; date.resolution:date对象表示日期的最小单位。这里是天。 date.today():返回一个表示当前本地日期的date对象; date.fromtimestamp(timestamp):根据给定的时间戮,返回一个date对象; ![]()
方法和属性 d1 = date(2011,06,03)#date对象
d1.year、date.month、date.day:年、月、日;
d1.replace(year, month, day):生成一个新的日期对象,用参数指定的年,月,日代替原有对象中的属性。(原有对象仍保持不变)
d1.timetuple():返回日期对应的time.struct_time对象;
d1.weekday():返回weekday,如果是星期一,返回0;如果是星期2,返回1,以此类推;
d1.isoweekday():返回weekday,如果是星期一,返回1;如果是星期2,返回2,以此类推;
d1.isocalendar():返回格式如(year,month,day)的元组;
d1.isoformat():返回格式如'YYYY-MM-DD’的字符串;
d1.strftime(fmt):和time模块format相同。
![]()
2、time类 datetime.time(hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ) 静态方法和字段 time.min、time.max:time类所能表示的最小、最大时间。其中,time.min = time(0, 0, 0, 0), time.max = time(23, 59, 59, 999999); time.resolution:时间的最小单位,这里是1微秒;
方法和属性 t1 = datetime.time(10,23,15)#time对象 ![]() 3、datetime类 datetime相当于date和time结合起来。 静态方法和字段 datetime.today():返回一个表示当前本地时间的datetime对象; datetime.now([tz]):返回一个表示当前本地时间的datetime对象,如果提供了参数tz,则获取tz参数所指时区的本地时间; datetime.utcnow():返回一个当前utc时间的datetime对象;#格林威治时间 datetime.fromtimestamp(timestamp[, tz]):根据时间戮创建一个datetime对象,参数tz指定时区信息; datetime.utcfromtimestamp(timestamp):根据时间戮创建一个datetime对象; datetime.combine(date, time):根据date和time,创建一个datetime对象; datetime.strptime(date_string, format):将格式字符串转换为datetime对象;
![]()
方法和属性 dt=datetime.now()#datetime对象
dt.year、month、day、hour、minute、second、microsecond、tzinfo:
dt.date():获取date对象;
dt.time():获取time对象;
dt. replace ([ year[ , month[ , day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ] ] ]):
dt. timetuple ()
dt. utctimetuple ()
dt. toordinal ()
dt. weekday ()
dt. isocalendar ()
dt. isoformat ([ sep] )
dt. ctime ():返回一个日期时间的C格式字符串,等效于time.ctime(time.mktime(dt.timetuple()));
dt. strftime (format)
4.timedelta类,时间加减 使用timedelta可以很方便的在日期上做天days,小时hour,分钟,秒,毫秒,微妙的时间计算,如果要计算月份则需要另外的办法。 #coding:utf-8
from datetime import *
dt = datetime.now() #日期减一天 dt1 = dt + timedelta(days=-1)#昨天 dt2 = dt - timedelta(days=1)#昨天 dt3 = dt + timedelta(days=1)#明天 delta_obj = dt3-dt print type(delta_obj),delta_obj#<type 'datetime.timedelta'> 1 day, 0:00:00 print delta_obj.days ,delta_obj.total_seconds()#1 86400.0 5、tzinfo时区类 #! /usr/bin/python
# coding=utf-8
from datetime import datetime, tzinfo,timedelta <> tzinfo是关于时区信息的类 tzinfo是一个抽象类,所以不能直接被实例化 > class UTC(tzinfo): <>UTC> def init(self,offset = 0): self._offset = offset
#北京时间 beijing = datetime(2011,11,11,0,0,0,tzinfo = UTC(8)) print "beijing time:",beijing #曼谷时间 bangkok = datetime(2011,11,11,0,0,0,tzinfo = UTC(7)) print "bangkok time",bangkok #北京时间转成曼谷时间 print "beijing-time to bangkok-time:",beijing.astimezone(UTC(7)) #计算时间差时也会考虑时区的问题 timespan = beijing - bangkok print "时差:",timespan #Output================== # beijing time: 2011-11-11 00:00:00+08:00 # bangkok time 2011-11-11 00:00:00+07:00 # beijing-time to bangkok-time: 2011-11-10 23:00:00+07:00 # 时差: -1 day, 23:00:00 hashlib加密hashlib主要提供字符加密功能,将md5和sha模块整合到了一起,支持md5,sha1, sha224, sha256, sha384, sha512等算法 具体应用#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#pyversion:python3.5 #owner:fuzj
import hashlib # ######## md5 ######## string = "beyongjie" md5 = hashlib.md5() md5.update(string.encode('utf-8')) #注意转码 res = md5.hexdigest() print("md5加密结果:",res) # ######## sha1 ######## sha1 = hashlib.sha1() sha1.update(string.encode('utf-8')) res = sha1.hexdigest() print("sha1加密结果:",res) # ######## sha256 ######## sha256 = hashlib.sha256() sha256.update(string.encode('utf-8')) res = sha256.hexdigest() print("sha256加密结果:",res) # ######## sha384 ######## sha384 = hashlib.sha384() sha384.update(string.encode('utf-8')) res = sha384.hexdigest() print("sha384加密结果:",res) # ######## sha512 ######## sha512= hashlib.sha512() sha512.update(string.encode('utf-8')) res = sha512.hexdigest() print("sha512加密结果:",res)
输出结果: md5加密结果: 0e725e477851ff4076f774dc312d4748 sha1加密结果: 458d32be8ea38b66300174970ab0a8c0b734252f sha256加密结果: 1e62b55bfd02977943f885f6a0998af7cc9cfb95c8ac4a9f30ecccb7c05ec9f4 sha384加密结果: e91cdf0d2570de5c96ee84e8a12cddf16508685e7a03b3e811099cfcd54b7f52183e20197cff7c07f312157f0ba4875b sha512加密结果: 3f0020a726e9c1cb5d22290c967f3dd1bcecb409a51a8088db520750c876aaec3f17a70d7981cd575ed4b89471f743f3f24a146a39d59f215ae3e208d0170073
注意:hashlib 加密啊的字符串类型为二进制编码,直接加密字符串会报如下错误: sha1 = hashlib.sha1()
sha1.update(string)
res = sha1.hexdigest()
print("sha1加密结果:",res)
TypeError: Unicode-objects must be encoded before hashing
可以使用encode进行转换 shaa1 = hashlib.sha1()
shaa1.update(string.encode('utf-8'))
res = shaa1.hexdigest() print("sha1采用encode转换加密结果:",res)
或者使用byte转换为二进制 shab1 = hashlib.sha1()
shab1.update(bytes(string,encoding='utf-8'))
res = shab1.hexdigest() print("sha1采用byte转换的结果:",res)
以上输出: sha1采用encode转换加密结果: 458d32be8ea38b66300174970ab0a8c0b734252f sha1采用byte转换的结果: 458d32be8ea38b66300174970ab0a8c0b734252f
常用方法
m = hashlib.md5()
m.update('a'.encode('utf-8')) res = m.hexdigest() print("第一次a加密:",res)
m.update('b'.encode('utf-8')) res = m.hexdigest() print("第二次b加密:",res) m1 = hashlib.md5() m1.update('b'.encode('utf-8')) res = m1.hexdigest() print("b单独加密:",res) m2 = hashlib.md5() m2.update('ab'.encode('utf-8')) res = m2.hexdigest() print("ab单独加密:",res) 输出结果: 第一次a加密: 0cc175b9c0f1b6a831c399e269772661 第二次b加密: 187ef4436122d1cc2f40dc2b92f0eba0 b单独加密: 92eb5ffee6ae2fec3ad71c777531578f ab单独加密: 187ef4436122d1cc2f40dc2b92f0eba0
高级加密以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。 low = hashlib.md5()
low.update('ab'.encode('utf-8')) res = low.hexdigest() print("普通加密:",res)
high = hashlib.md5(b'beyondjie') high.update('ab'.encode('utf-8')) res = high.hexdigest() print("采用key加密:",res) 输出结果: 普通加密: 187ef4436122d1cc2f40dc2b92f0eba0 采用key加密: 1b073f6b8cffe609751e4c98537b7653
附加HMAC-SHA1各语言版本实现在各大开放平台大行其道的互联网开发潮流中,调用各平台的API接口过程中,无一例外都会用到计算签名值(sig值)。而在各种计算签名的方法中,经常被采用的就是HMAC-SHA1,现对HMAC-SHA1做一个简单的介绍:
Token:即接口的key data:要加密的数据
1 logging模块简介logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
2 logging模块使用2.1 基本使用配置logging基本的设置,然后在控制台输出日志, import logging logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish") 运行时,控制台输出,
logging中可以选择很多消息级别,如debug、info、warning、error以及critical。通过赋予logger或者handler不同的级别,开发者就可以只输出错误信息到特定的记录文件,或者在调试时只记录调试信息。 例如,我们将logger的级别改为DEBUG,再观察一下输出结果, logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s') 控制台输出,可以发现,输出了debug的信息。
logging.basicConfig函数各参数: filename:指定日志文件名; filemode:和file函数意义相同,指定日志文件的打开模式,'w'或者'a'; format:指定输出的格式和内容,format可以输出很多有用的信息,
datefmt:指定时间格式,同time.strftime(); level:设置日志级别,默认为logging.WARNNING; stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略; 2.2 将日志写入到文件2.2.1 将日志写入到文件 设置logging,创建一个FileHandler,并对输出消息的格式进行设置,将其添加到logger,然后将日志写入到指定的文件中, import logging logger = logging.getLogger(__name__) logger.setLevel(level = logging.INFO) handler = logging.FileHandler("log.txt") handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish") log.txt中日志数据为,
2.2.2 将日志同时输出到屏幕和日志文件 logger中添加StreamHandler,可以将日志输出到屏幕上, import logging logger = logging.getLogger(__name__) logger.setLevel(level = logging.INFO) handler = logging.FileHandler("log.txt") handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) console = logging.StreamHandler() console.setLevel(logging.INFO) logger.addHandler(handler) logger.addHandler(console) logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish") 可以在log.txt文件和控制台中看到,
可以发现,logging有一个日志处理的主对象,其他处理方式都是通过addHandler添加进去,logging中包含的handler主要有如下几种,
2.2.3 日志回滚 使用RotatingFileHandler,可以实现日志回滚, import logging from logging.handlers import RotatingFileHandler logger = logging.getLogger(__name__) logger.setLevel(level = logging.INFO) #定义一个RotatingFileHandler,最多备份3个日志文件,每个日志文件最大1K rHandler = RotatingFileHandler("log.txt",maxBytes = 1*1024,backupCount = 3) rHandler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') rHandler.setFormatter(formatter) console = logging.StreamHandler() console.setLevel(logging.INFO) console.setFormatter(formatter) logger.addHandler(rHandler) logger.addHandler(console) logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish") 可以在工程目录中看到,备份的日志文件,
2.3 设置消息的等级可以设置不同的日志等级,用于控制日志的输出,
2.4 捕获tracebackPython中的traceback模块被用于跟踪异常返回信息,可以在logging中记录下traceback, 代码, import logging logger = logging.getLogger(__name__) logger.setLevel(level = logging.INFO) handler = logging.FileHandler("log.txt") handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) console = logging.StreamHandler() console.setLevel(logging.INFO) logger.addHandler(handler) logger.addHandler(console) logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") try: open("sklearn.txt","rb") except (SystemExit,KeyboardInterrupt): raise except Exception: logger.error("Faild to open sklearn.txt from logger.error",exc_info = True) logger.info("Finish") 控制台和日志文件log.txt中输出,
也可以使用logger.exception(msg,_args),它等价于logger.error(msg,exc_info = True,_args), 将
替换为,
控制台和日志文件log.txt中输出,
2.5 多模块使用logging主模块mainModule.py, import logging import subModule logger = logging.getLogger("mainModule") logger.setLevel(level = logging.INFO) handler = logging.FileHandler("log.txt") handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) console = logging.StreamHandler() console.setLevel(logging.INFO) console.setFormatter(formatter) logger.addHandler(handler) logger.addHandler(console) logger.info("creating an instance of subModule.subModuleClass") a = subModule.SubModuleClass() logger.info("calling subModule.subModuleClass.doSomething") a.doSomething() logger.info("done with subModule.subModuleClass.doSomething") logger.info("calling subModule.some_function") subModule.som_function() logger.info("done with subModule.some_function") 子模块subModule.py, import logging module_logger = logging.getLogger("mainModule.sub") class SubModuleClass(object): def init(self): self.logger = logging.getLogger("mainModule.sub.module") self.logger.info("creating an instance in SubModuleClass") def doSomething(self): self.logger.info("do something in SubModule") a = [] a.append(1) self.logger.debug("list a = " + str(a)) self.logger.info("finish something in SubModuleClass") def som_function(): module_logger.info("call function some_function") 执行之后,在控制和日志文件log.txt中输出,
首先在主模块定义了logger'mainModule',并对它进行了配置,就可以在解释器进程里面的其他地方通过getLogger('mainModule')得到的对象都是一样的,不需要重新配置,可以直接使用。定义的该logger的子logger,都可以共享父logger的定义和配置,所谓的父子logger是通过命名来识别,任意以'mainModule'开头的logger都是它的子logger,例如'mainModule.sub'。 实际开发一个application,首先可以通过logging配置文件编写好这个application所对应的配置,可以生成一个根logger,如'PythonAPP',然后在主函数中通过fileConfig加载logging配置,接着在application的其他地方、不同的模块中,可以使用根logger的子logger,如'PythonAPP.Core','PythonAPP.Web'来进行log,而不需要反复的定义和配置各个模块的logger。 3 通过JSON或者YAML文件配置logging模块尽管可以在Python代码中配置logging,但是这样并不够灵活,最好的方法是使用一个配置文件来配置。在Python 2.7及以后的版本中,可以从字典中加载logging配置,也就意味着可以通过JSON或者YAML文件加载日志的配置。 3.1 通过JSON文件配置JSON配置文件,
通过JSON加载配置文件,然后通过logging.dictConfig配置logging, import json import logging.config import os def setup_logging(default_path = "logging.json",default_level = logging.INFO,env_key = "LOG_CFG"): path = default_path value = os.getenv(env_key,None) if value: path = value if os.path.exists(path): with open(path,"r") as f: config = json.load(f) logging.config.dictConfig(config) else: logging.basicConfig(level = default_level) def func(): logging.info("start func")
if name == "main": setup_logging(default_path = "logging.json") func() 3.2 通过YAML文件配置通过YAML文件进行配置,比JSON看起来更加简介明了,
通过YAML加载配置文件,然后通过logging.dictConfig配置logging, import yaml import logging.config import os def setup_logging(default_path = "logging.yaml",default_level = logging.INFO,env_key = "LOG_CFG"): path = default_path value = os.getenv(env_key,None) if value: path = value if os.path.exists(path): with open(path,"r") as f: config = yaml.load(f) logging.config.dictConfig(config) else: logging.basicConfig(level = default_level) def func(): logging.info("start func")
if name == "main": setup_logging(default_path = "logging.yaml") func()
subprocess模块subprocess是Python 2.4中新增的一个模块,它允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码。这个模块的目的在于替换几个旧的模块和方法,如:
1. subprocess模块中的常用函数
2. 上面各函数的定义及参数说明函数参数列表:
参数说明:
3. subprocess.CompletedProcess类介绍需要说明的是,subprocess.run()函数是Python3.5中新增的一个高级函数,其返回值是一个subprocess.CompletedPorcess类的实例,因此,subprocess.completedPorcess类也是Python 3.5中才存在的。它表示的是一个已结束进程的状态信息,它所包含的属性如下:
4. 实例subprocess.run()
subprocess.call()
suprocess.check_call()
sbuprocess.check_output()
subprocess.getoutput()与subprocess.getstatusoutput()
三、subprocess.Popen介绍该类用于在一个新的进程中执行一个子程序。前面我们提到过,上面介绍的这些函数都是基于subprocess.Popen类实现的,通过使用这些被封装后的高级函数可以很方面的完成一些常见的需求。由于subprocess模块底层的进程创建和管理是由Popen类来处理的,因此,当我们无法通过上面哪些高级函数来实现一些不太常见的功能时就可以通过subprocess.Popen类提供的灵活的api来完成。 1.subprocess.Popen的构造函数
参数说明:
2. subprocess.Popen类的实例可调用的方法
关于communicate()方法的说明:
3. subprocess.Popen使用实例实例1:
实例2:
实例3:
实例4:实现类似
四、总结那么我们到底该用哪个模块、哪个函数来执行命令与系统及系统进行交互呢?下面我们来做个总结:
json ,pickle模块JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。JSON的数据格式其实就是python里面的字典格式,里面可以包含方括号括起来的数组,也就是python里面的列表。 在python中,有专门处理json格式的模块—— json 和 picle模块 Json 模块提供了四个方法: dumps、dump、loads、load
pickle 模块也提供了四个功能:dumps、dump、loads、load
一. dumps 和 dump:
dumps和dump 序列化方法
dumps只完成了序列化为str,
dump必须传文件描述符,将序列化的str保存到文件中
查看源码:
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):
# Serialize ``obj`` to a JSON formatted ``str``. # 序列号 “obj” 数据类型 转换为 JSON格式的字符串
def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):
"""Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). 我理解为两个动作,一个动作是将”obj“转换为JSON格式的字符串,还有一个动作是将字符串写入到文件中,也就是说文件描述符fp是必须要的参数 """
示例代码: >>> import json
>>> json.dumps([]) # dumps可以格式化所有的基本数据类型为字符串
'[]' >>> json.dumps(1) # 数字 '1' >>> json.dumps('1') # 字符串 '"1"' >>> dict = {"name":"Tom", "age":23} >>> json.dumps(dict) # 字典 '{"name": "Tom", "age": 23}'
a = {"name":"Tom", "age":23} with open("test.json", "w", encoding='utf-8') as f: # indent 超级好用,格式化保存字典,默认为None,小于0为零个空格 f.write(json.dumps(a, indent=4)) # json.dump(a,f,indent=4) # 和上面的效果一样
保存的文件效果:
二. loads 和 load loads和load 反序列化方法
loads 只完成了反序列化,
load 只接收文件描述符,完成了读取文件和反序列化
查看源码: def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
"""Deserialize ``s`` (a ``str`` instance containing a JSON document) to a Python object.
将包含str类型的JSON文档反序列化为一个python对象"""
def load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
"""Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object.
将一个包含JSON格式数据的可读文件饭序列化为一个python对象"""
实例: >>> json.loads('{"name":"Tom", "age":23}')
{'age': 23, 'name': 'Tom'}
import json
with open("test.json", "r", encoding='utf-8') as f: aa = json.loads(f.read()) f.seek(0) bb = json.load(f) # 与 json.loads(f.read()) print(aa) print(bb)
# 输出: {'name': 'Tom', 'age': 23} {'name': 'Tom', 'age': 23} 三. json 和 pickle 模块 json模块和pickle模块都有 dumps、dump、loads、load四种方法,而且用法一样。 不用的是json模块序列化出来的是通用格式,其它编程语言都认识,就是普通的字符串, 而picle模块序列化出来的只有python可以认识,其他编程语言不认识的,表现为乱码 不过picle可以序列化函数,但是其他文件想用该函数,在该文件中需要有该文件的定义(定义和参数必须相同,内容可以不同) 四. python对象(obj) 与json对象的对应关系 +-------------------+---------------+ | Python | JSON | +===================+===============+ | dict | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str | string | +-------------------+---------------+ | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ | False | false | +-------------------+---------------+ | None | null | +-------------------+---------------+
五. 总结 1. json序列化方法: dumps:无文件操作 dump:序列化+写入文件 2. json反序列化方法: loads:无文件操作 load: 读文件+反序列化 3. json模块序列化的数据 更通用 picle模块序列化的数据 仅python可用,但功能强大,可以序列号函数 4. json模块可以序列化和反序列化的 数据类型 见 python对象(obj) 与json对象的对应关系表 5. 格式化写入文件利用 indent = 4 ElementTree是python的XML处理模块
ElementTree是python的XML处理模块,它提供了一个轻量级的对象模型。它在Python2.5以后成为Python标准库的一部分,但是Python2.4之前需要单独安装。在使用ElementTree模块时,需要import xml.etree.ElementTree的操作。
ElementTree表示整个XML节点树,而Element表示节点数中的一个单独的节点。
构建
ElementTree(tag),其中tag表示根节点,初始化一个ElementTree对象。
Element(tag, attrib={}, **extra)函数用来构造XML的一个根节点,其中tag表示根节点的名称,attrib是一个可选项,表示节点的属性。
SubElement(parent, tag, attrib={}, **extra)用来构造一个已经存在的节点的子节点
Element.text和SubElement.text表示element对象的额外的内容属性,Element.tag和Element.attrib分别表示element对象的标签和属性。
ElementTree.write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml'),函数新建一个XML文件,并且将节点数数据写入XML文件中。
#新建xml文件 def buildNewsXmlFile(): #设置一个新节点,并设置其标签为root root = ET.Element("root")
解析和修改XML文件
ElementTree.parse(source, parser=None),将xml文件加载并返回ElementTree对象。parser是一个可选的参数,如果为空,则默认使用标准的XMLParser解析器。
ElementTree.getroot(),得到根节点。返回根节点的element对象。
Element.remove(tag),删除root下名称为tag的子节点
以下函数,ElementTree和Element的对象都包含。
find(match),得到第一个匹配match的子节点,match可以是一个标签名称或者是路径。返回个element
findtext(match,default=None),得到第一个配置的match的element的内容
findall(match),得到匹配match下的所有的子节点,match可以是一个标签或者是路径,它会返回一个list,包含匹配的elements的信息
iter(tag),创建一个以当前节点为根节点的iterator。
这里有一个xml文件
现在是解析xml文件的代码
第一次的输出是:1,2008,14100
第二次的输出是:1,2008,14100,4,2011,59900,68,2011,13600
修改后的xml文件为
configparser 简介configparser 是 Pyhton 标准库中用来解析配置文件的模块,并且内置方法和字典非常接近。Python2.x 中名为 ConfigParser,3.x 已更名小写,并加入了一些新功能。
“[ ]”包含的为 section,section 下面为类似于 key - value 的配置内容; configparser 常用方法初始化实例使用 configparser 首先需要初始化实例,并读取配置文件:
或者可以直接读字典
获取所有 sections
获取指定 section 的 keys & values
获取指定 section 的 keys
获取指定 key 的 value
检查
添加
删除
关于 [DEFAULT][DEFAULT] 一般包含 ini 格式配置文件的默认项,所以 configparser 部分方法会自动跳过这个 section 。
但指定删除和修改 [DEFAULT] 里的 keys & values 是可以的:
还有个特殊的是,has_section() 也无效,可以和 in 区别使用
randmon(获取随机数) random.random random.uniform print random.uniform(10, 20) print random.uniform(20, 10) # 18.7356606526 # 12.5798298022 random.randint print random.randint(12, 20) # 生成的随机数 n: 12 <= n <= 20 print random.randint(20, 20) # 结果永远是20 # print random.randint(20, 10) # 该语句是错误的。下限必须小于上限 random.randrange random.choice print random.choice("学习Python") print random.choice(["JGood", "is", "a", "handsome", "boy"]) print random.choice(("Tuple", "List", "Dict")) random.shuffle p = ["Python", "is", "powerful", "simple", "and so on..."] random.shuffle(p) print p # ['powerful', 'simple', 'is', 'Python', 'and so on...'] random.sample list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] slice = random.sample(list, 5) # 从list中随机获取5个元素,作为一个片断返回 print slice print list # 原有序列并没有改变
>>> import random
>>> random.randint(0,99) # 21 随机选取0到100间的偶数:
>>> import random
>>> random.randrange(0, 101, 2) # 42 随机浮点数:
>>> import random
>>> random.random() 0.85415370477785668 >>> random.uniform(1, 10) # 5.4221167969800881 随机字符:
>>> import random
>>> random.choice('abcdefg&#%^*f') # 'd' 多个字符中选取特定数量的字符:
>>> import random
random.sample('abcdefghij', 3) # ['a', 'd', 'b'] 多个字符中选取特定数量的字符组成新字符串:
>>> import random
>>> import string >>> string.join( random.sample(['a','b','c','d','e','f','g','h','i','j'], 3) ).replace(" ","") # 'fih' 随机选取字符串:
>>> import random
>>> random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] ) # 'lemon' 洗牌:
>>> import random
>>> items = [1, 2, 3, 4, 5, 6] >>> random.shuffle(items) >>> items # [3, 2, 5, 6, 4, 1]
shutil模块
copy()
copy2()
copyfileobj()
copyfile()
copytree()
copymode()
copystat()
rmtree()
move()
which()
disk_usage()
归档和解包操作
make_archive()
unpack_archive()
get_archive_formats()
get_unpack_formats()
paramikoparamiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。 1、下载安装
2、模块使用 ![]() #!/usr/bin/env python
#coding:utf-8
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('192.168.1.108', 22, 'alex', '123') stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() ssh.close(); ![]() import paramiko
private_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(private_key_path) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('主机名 ', 端口, '用户名', key) stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() ssh.close() ![]() import os,sys
import paramiko
t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',password='123') sftp = paramiko.SFTPClient.from_transport(t) sftp.put('/tmp/test.py','/tmp/test.py') t.close() import os,sys import paramiko t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',password='123') sftp = paramiko.SFTPClient.from_transport(t) sftp.get('/tmp/test.py','/tmp/test2.py') t.close() ![]() import paramiko
pravie_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(pravie_key_path) t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',pkey=key) sftp = paramiko.SFTPClient.from_transport(t) sftp.put('/tmp/test3.py','/tmp/test3.py') t.close() import paramiko pravie_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(pravie_key_path) t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',pkey=key) sftp = paramiko.SFTPClient.from_transport(t) sftp.get('/tmp/test3.py','/tmp/test4.py') t.close() requestsPython标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了。它是为另一个时代、另一个互联网所创建的。它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务。 ![]() import urllib.request
f = urllib.request.urlopen('http://www.//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') result = f.read().decode('utf-8') ![]() import urllib.request
req = urllib.request.Request('http://www./') req.add_header('Referer', 'http://www./') r = urllib.request.urlopen(req) result = f.read().decode('utf-8') 注:更多见Python官方文档:https://docs./3.5/library/urllib.request.html#module-urllib.request Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作。 1、安装模块
2、使用模块 ![]() # 1、无参数实例
import requests
ret = requests.get('https://github.com/timeline.json') print(ret.url) print(ret.text) # 2、有参数实例 import requests payload = {'key1': 'value1', 'key2': 'value2'} ret = requests.get("http:///get", params=payload) print(ret.url) print(ret.text)
![]() # 1、基本POST实例
import requests
payload = {'key1': 'value1', 'key2': 'value2'} ret = requests.post("http:///post", data=payload) print(ret.text) # 2、发送请求头和数据实例 import requests import json url = 'https://api.github.com/some/endpoint' payload = {'some': 'data'} headers = {'content-type': 'application/json'} ret = requests.post(url, data=json.dumps(payload), headers=headers) print(ret.text) print(ret.cookies)
![]() requests.get(url, params=None, **kwargs)
requests.post(url, data=None, json=None, **kwargs)
requests.put(url, data=None, **kwargs)
requests.head(url, **kwargs)
requests.delete(url, **kwargs)
requests.patch(url, data=None, **kwargs) requests.options(url, **kwargs) # 以上方法均是在此方法的基础上构建 requests.request(method, url, **kwargs)
更多requests模块相关的文档见:http://cn./zh_CN/latest/ 3、Http请求和XML实例 实例:检测QQ账号是否在线 ![]() import urllib
import requests
from xml.etree import ElementTree as ET
# 使用内置模块urllib发送HTTP请求,或者XML格式内容 <> f = urllib.request.urlopen('http://www.//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') result = f.read().decode('utf-8') > # 使用第三方模块requests发送HTTP请求,或者XML格式内容 r = requests.get('http://www.//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') result = r.text # 解析XML格式内容 node = ET.XML(result) # 获取内容 if node.text == "Y": print("在线") else: print("离线") 实例:查看火车停靠信息 ![]() import urllib
import requests
from xml.etree import ElementTree as ET
# 使用内置模块urllib发送HTTP请求,或者XML格式内容 <> f = urllib.request.urlopen('http://www./WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') result = f.read().decode('utf-8') > # 使用第三方模块requests发送HTTP请求,或者XML格式内容 r = requests.get('http://www./WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') result = r.text # 解析XML格式内容 root = ET.XML(result) for node in root.iter('TrainDetailInfo'): print(node.find('TrainStation').text,node.find('StartTime').text,node.tag,node.attrib) 注:更多接口猛击这里 paramiko模块
import paramiko
# 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在known_hosts文件上的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname="192.168.0.99", port=22, username="root", password="rootroot") # 执行命令 stdin, stdout, stderr = ssh.exec_command('df') # 获取结果 result = stdout.read().decode() # 获取错误提示(stdout、stderr只会输出其中一个) err = stderr.read() # 关闭连接 ssh.close() print(stdin, result, err) 注:如果注释“ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())”这句,会报错。 类似问题可以为linux系统中~/.ssh/known_hosts文件中的内容。 二、实现SFTP功能 import paramiko
# 连接虚拟机centos上的ip及端口
transport = paramiko.Transport(("192.168.0.99", 22)) transport.connect(username="root", password="rootroot") # 将实例化的Transport作为参数传入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 将“calculator.py”上传到filelist文件夹中 sftp.put('D:\python库\Python_shell\day05\calculator.py', '/filelist/calculator.py') # 将centos中的aaa.txt文件下载到桌面 sftp.get('/filedir/aaa.txt', r'C:\Users\duany_000\Desktop\test_aaa.txt') transport.close()
注:如果遇到Windows中路径问题,链接如下网址http://blog.csdn.net/elang6962/article/details/68068126 三、使用秘钥实现SSH功能 import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 创建SSH对象 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='192.168.79.9', port=22, username='root', pkey=private_key) stdin, stdout, stderr = ssh.exec_command('ifconfig') res_out = stdout.read() print(res_out.decode()) ssh.close()
四、使用秘钥实现SFTP功能 import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 连接虚拟机centos上的ip及端口 transport = paramiko.Transport(("192.168.79.9", 22)) transport.connect(username="root", pkey=private_key) # 将实例化的Transport作为参数传入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 将“calculator.py”上传到filelist文件夹中 sftp.put('D:\python库\Python_shell\day05\calculator.py', '/filedir/calculator.py') # 将centos中的aaa.txt文件下载到桌面 sftp.get('/filedir/oldtext.txt', r'C:\Users\duany_000\Desktop\oldtext.txt') transport.close()
|
|