logging

简单应用

将日志打印到屏幕

 import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

可见,默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默认的日志格式为日志级别:Logger名称:用户输出消息。

灵活配置日志级别,日志格式,输出位置

 import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a,%d %b %Y %H:%M:%S',
filename='test.log',
) # filemode='a' logging.debug('debug message11')
logging.info('info message22')
logging.warning('hello error33')
logging.error('error message44')
logging.critical('critical message55')

保存的内容为

Wed,14 Sep 2016 16:09:48 modue_test.py[line:46] DEBUG debug message11
Wed,14 Sep 2016 16:09:48 modue_test.py[line:47] INFO info message22
Wed,14 Sep 2016 16:09:48 modue_test.py[line:48] WARNING hello error33
Wed,14 Sep 2016 16:09:48 modue_test.py[line:49] ERROR error message44
Wed,14 Sep 2016 16:09:48 modue_test.py[line:50] CRITICAL critical message55

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

logging.basicConfig()(用默认日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)

 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) 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')

运行后在文件与屏幕上同时输出

2016-09-14 16:13:43,774 - root - DEBUG - logger debug message
2016-09-14 16:13:43,775 - root - INFO - logger info message
2016-09-14 16:13:43,775 - root - WARNING - logger warning message
2016-09-14 16:13:43,775 - root - ERROR - logger error message
2016-09-14 16:13:43,775 - root - CRITICAL - logger critical message

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': '',
'Compression': 'yes',
'CompressionLevel': ''} config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '' # mutates the parser
topsecret['ForwardX11'] = 'no' # same here
config['DEFAULT']['ForwardX11'] = 'yes'<br>
with open('example.ini', 'w') as configfile:
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','') config.write(open('i.cfg', "w")) 增删改查

 json & pickle

序列化

我们把对象(变量)从内存中变成可存储或传输的过程称为序列化

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

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

json

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为json,因为json表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。json不仅是标准格式,而且比XML更快,而且可以直接在Wab页面中读取,非常方便。

 import json

 dic={'name':'alvin','age':23,'sex':'male'}
print(type(dic)) #<class 'dict'> j=json.dumps(dic)
print(type(j)) #<class 'str'> f=open('序列化对象','w')
f.write(j) #-------------------等价于json.dump(dic,f)
f.close()
#-----------------------------反序列化<br>
import json
f=open('序列化对象')
data=json.loads(f.read()) # 等价于data=json.load(f)
 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 注意点

保存的时候有两个方法dump和dumps

读取的时候有两个方法load和loads

 import json
# import pickle
f = open("666.txt", "w") dic = {"j": "d", "": "dd"}
# dic = json.dumps(dic)
# f.write(dic)
json.dump(dic, f)
# dic = pickle.dumps(dic)
print(type(dic)) f.close() ######### 注意两种方法的不同 ##########
import json f = open("666.txt", "r") # data = json.loads(f.read())
data = json.load(f)
print(data)
# print(type(f.read()))
f.close()

pickle

pickle的使用方法与json类似,但是pickle只能用于python,并且能保存json不能保存的类型

 subprocess

subprocess模块的主要功能是执行外部的命令和程序

subprocess模块允许一个进程创建一个新的子进程,通过管道连接到子进程的stdin/stdout/stderr,获取子进程的返回值等操作

模块有一个重要类: Popen

 # Popen它的构造函数如下:

 subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None,stderr=None, preexec_fn=None, close_fds=False, shell=False,<br>                 cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
 # 参数args可以是字符串或者序列类型(如:list,元组),用于指定进程的可执行文件及其参数。
# 如果是序列类型,第一个元素通常是可执行文件的路径。我们也可以显式的使用executeable参
# 数来指定可执行文件的路径。在windows操作系统上,Popen通过调用CreateProcess()来创
# 建子进程,CreateProcess接收一个字符串参数,如果args是序列类型,系统将会通过
# list2cmdline()函数将序列类型转换为字符串。
#
#
# 参数bufsize:指定缓冲。我到现在还不清楚这个参数的具体含义,望各个大牛指点。
#
# 参数executable用于指定可执行程序。一般情况下我们通过args参数来设置所要运行的程序。如
# 果将参数shell设为True,executable将指定程序使用的shell。在windows平台下,默认的
# shell由COMSPEC环境变量来指定。
#
# 参数stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。他们可以是PIPE,
# 文件描述符或文件对象,也可以设置为None,表示从父进程继承。
#
# 参数preexec_fn只在Unix平台下有效,用于指定一个可执行对象(callable object),它将
# 在子进程运行之前被调用。
#
# 参数Close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会
# 继承父进程的输入、输出、错误管道。我们不能将close_fds设置为True同时重定向子进程的标准
# 输入、输出与错误(stdin, stdout, stderr)。
#
# 如果参数shell设为true,程序将通过shell来执行。
#
# 参数cwd用于设置子进程的当前目录。
#
# 参数env是字典类型,用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父
# 进程中继承。
#
# 参数Universal_newlines:不同操作系统下,文本的换行符是不一样的。如:windows下
# 用’/r/n’表示换,而Linux下用’/n’。如果将此参数设置为True,Python统一把这些换行符当
# 作’/n’来处理。
#
# 参数startupinfo与createionflags只在windows下用效,它们将被传递给底层的
# CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等。 parameter

参数介绍

简单命令

 # 此为linux下运行
import subprocess a=subprocess.Popen('ls')# 创建一个新的进程,与主进程不同步 print('>>>>>>>',a)#a是Popen的一个实例对象 '''
>>>>>>> <subprocess.Popen object at 0x10185f860>
__init__.py
__pycache__
log.py
main.py ''' # subprocess.Popen('ls -l',shell=True) # subprocess.Popen(['ls','-l'])

subprocess.PIPE

在创建Popen对象时,subprocess.PIPE可以初始化stdin,std,out,stderr参数。表示与子进程通信的标准流

 import subprocess

 # subprocess.Popen('ls')
p=subprocess.Popen('ls',stdout=subprocess.PIPE)#结果跑哪去啦? print(p.stdout.read())#这这呢:b'__pycache__\nhello.py\nok.py\nweb\n'

这是因为subprocess创建了子进程,结果本来在子进程中,if想要执行结果转到主进程中,就需要一个管道,即: stdout = subprocess.PIPE

Popen的方法

Popen.poll()
用于检查子进程是否已经结束。设置并返回returncode属性。 Popen.wait()
等待子进程结束。设置并返回returncode属性。 Popen.communicate(input=None)
与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。 Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如 果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。 Popen.send_signal(signal)
向子进程发送信号。 Popen.terminate()
停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。 Popen.kill()
杀死子进程。 Popen.stdin
如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令。否则返回None。 Popen.stdout
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。 Popen.stderr
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。 Popen.pid
获取子进程的进程ID。 Popen.returncode
获取进程的返回值。如果进程还没有结束,返回None。

subprocess模块的工具函数

supprocess模块提供了一些函数,方便我们用于创建进程来实现一些简单的功能。

subprocess.call(*popenargs, **kwargs)
运行命令。该函数将一直等待到子进程运行结束,并返回进程的returncode。如果子进程不需要进行交 互,就可以使用该函数来创建。 subprocess.check_call(*popenargs, **kwargs)
与subprocess.call(*popenargs, **kwargs)功能一样,只是如果子进程返回的returncode不为0的话,将触发CalledProcessError异常。在异常对象中,包 括进程的returncode信息。 check_output(*popenargs, **kwargs) # 重要
与call()方法类似,以byte string的方式返回子进程的输出,如果子进程的返回值不是0,它抛出CalledProcessError异常,这个异常中的returncode包含返回码,output属性包含已有的输出。 getstatusoutput(cmd)/getoutput(cmd)
这两个函数仅仅在Unix下可用,它们在shell中执行指定的命令cmd,前者返回(status, output),后者返回output。其中,这里的output包括子进程的stdout和stderr。
 import subprocess

 #
# subprocess.call('ls',shell=True)
'''
hello.py
ok.py
web
'''
# data=subprocess.call('ls',shell=True)
# print(data)
'''
hello.py
ok.py
web
''' #
# subprocess.check_call('ls',shell=True) '''
hello.py
ok.py
web
'''
# data=subprocess.check_call('ls',shell=True)
# print(data)
'''
hello.py
ok.py
web
'''
# 两个函数区别:只是如果子进程返回的returncode不为0的话,将触发CalledProcessError异常 #
# subprocess.check_output('ls')#无结果 # data=subprocess.check_output('ls')
# print(data) #b'hello.py\nok.py\nweb\n' 演示

最新文章

  1. Android-环境问题
  2. React-Native学习系列(一)
  3. 【nodejs笔记4】搭建多人博客&lt;内含http请求的get post方法区别&gt;
  4. 26、ASP.NET MVC入门到精通——后台管理区域及分离、Js压缩、css、jquery扩展
  5. linux dd 命令详解
  6. 浅析word-break work-wrap区别
  7. html基础 样式
  8. IE6 7下常见CSS兼容性处理
  9. 每天一个linux命令(44):top命令
  10. OSI七层与TCP/IP五层网络架构详解
  11. TSQL的连乘
  12. ruby学习总结02
  13. python学习笔记(Tkinter编程利用Treeview实现表格自动更新)
  14. Maven多层嵌套
  15. action找不到
  16. iOS导航标题不居中问题(转载)
  17. ASP.NET MVC5+EF6+EasyUI 后台管理系统(82)-Easyui Datagrid批量操作(编辑,删除,添加)
  18. 微信小程序开发入门
  19. centos6上调整lv逻辑卷
  20. (后端)异常不仅仅是try/catch

热门文章

  1. awk笔记1
  2. python高级编程之元类(第3部分结束)
  3. SQL记录-字符串的截取与拼接
  4. socket——本地服务器和android手机客户端通讯(防止中文乱码)
  5. ie11加载不了css的问题
  6. JavaScript --------------继前面继承方式-------总结
  7. OAuth协议与第三方登录:(QQ,百度,微信,微博)
  8. OpenCV——分水岭算法
  9. ElasticSearch入门知识扫盲
  10. Array类型(一)