logging

简单应用

将日志打印到屏幕



1 import logging  
2 logging.debug('debug message')  
3 logging.info('info message')  
4 logging.warning('warning message')  
5 logging.error('error message')  
6 logging.critical('critical message')



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

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



1 import logging
 2 logging.basicConfig(level=logging.DEBUG,
 3                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
 4                     datefmt='%a,%d %b %Y %H:%M:%S',
 5                     filename='test.log',
 6                     )  # filemode='a'
 7 
 8 
 9 logging.debug('debug message11')
10 logging.info('info message22')
11 logging.warning('hello error33')
12 logging.error('error message44')
13 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)



1 import logging
 2 
 3 logger = logging.getLogger()
 4 # 创建一个handler,用于写入日志文件
 5 fh = logging.FileHandler('test.log')
 6 
 7 # 再创建一个handler,用于输出到控制台
 8 ch = logging.StreamHandler()
 9 
10 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
11 
12 fh.setFormatter(formatter)
13 
14 ch.setFormatter(formatter)
15 
16 logger.addHandler(fh)
17  logger.addHandler(ch)
18 
19 logger.setLevel(logging.DEBUG)
20 
21 logger.debug('logger debug message')
22 logger.info('logger info message')
23 logger.warning('logger warning message')
24 logger.error('logger error message')
25 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 模块

来看一个好软件的常见文档格式如下:



1 [DEFAULT]
 2 ServerAliveInterval = 45
 3 Compression = yes
 4 CompressionLevel = 9
 5 ForwardX11 = yes
 6   
 7 [bitbucket.org]
 8 User = hg
 9   
10 [topsecret.server.com]
11 Port = 50022
12 ForwardX11 = no



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



1 import configparser
 2   
 3 config = configparser.ConfigParser()
 4 config["DEFAULT"] = {'ServerAliveInterval': '45',
 5                       'Compression': 'yes',
 6                      'CompressionLevel': '9'}
 7   
 8 config['bitbucket.org'] = {}
 9 config['bitbucket.org']['User'] = 'hg'
10 config['topsecret.server.com'] = {}
11 topsecret = config['topsecret.server.com']
12 topsecret['Host Port'] = '50022'     # mutates the parser
13 topsecret['ForwardX11'] = 'no'  # same here
14 config['DEFAULT']['ForwardX11'] = 'yes'<br>
15 with open('example.ini', 'w') as configfile:
16    config.write(configfile)



增删改查




Fast Api 调用Session_python

Fast Api 调用Session_python_02

1 import configparser
 2 
 3 config = configparser.ConfigParser()
 4 
 5 #---------------------------------------------查
 6 print(config.sections())   #[]
 7 
 8 config.read('example.ini')
 9 
10 print(config.sections())   #['bitbucket.org', 'topsecret.server.com']
11 
12 print('bytebong.com' in config)# False
13 
14 print(config['bitbucket.org']['User']) # hg
15 
16 print(config['DEFAULT']['Compression']) #yes
17 
18 print(config['topsecret.server.com']['ForwardX11'])  #no
19 
20 
21 for key in config['bitbucket.org']:
22     print(key)
23 
24 
25 # user
26 # serveraliveinterval
27 # compression
28 # compressionlevel
29 # forwardx11
30 
31 
32 print(config.options('bitbucket.org'))#['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
33 print(config.items('bitbucket.org'))  #[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')]
34 
35 print(config.get('bitbucket.org','compression'))#yes
36 
37 
38 #---------------------------------------------删,改,增(config.write(open('i.cfg', "w")))
39 
40 
41 config.add_section('yuan')
42 
43 config.remove_section('topsecret.server.com')
44 config.remove_option('bitbucket.org','user')
45 
46 config.set('bitbucket.org','k1','11111')
47 
48 config.write(open('i.cfg', "w"))
49 
50 增删改查


View Code


 json & pickle

序列化

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

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

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

json

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



1 import json
 2  
 3 dic={'name':'alvin','age':23,'sex':'male'}
 4 print(type(dic))   #<class 'dict'>
 5  
 6 j=json.dumps(dic)
 7 print(type(j))  #<class 'str'>
 8  
 9  
10 f=open('序列化对象','w')
11 f.write(j)   #-------------------等价于json.dump(dic,f)
12 f.close()
13 #-----------------------------反序列化<br>
14 import json
15 f=open('序列化对象')
16 data=json.loads(f.read())  #  等价于data=json.load(f)



1 import json
 2 #dct="{'1':111}"#json 不认单引号
 3 #dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1}
 4 
 5 dct='{"1":"111"}'
 6 print(json.loads(dct))
 7 
 8 #conclusion:
 9 #        无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
10 
11 注意点



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

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



1 import json
 2 # import pickle
 3 f = open("666.txt", "w")
 4 
 5 dic = {"j": "d", "6": "dd"}
 6 # dic = json.dumps(dic)
 7 # f.write(dic)
 8 json.dump(dic, f)
 9 # dic = pickle.dumps(dic)
10 print(type(dic))
11 
12 
13 f.close()
14 
15 #########  注意两种方法的不同  ##########
16 import json
17 
18 f = open("666.txt", "r")
19 
20 # data = json.loads(f.read())
21 data = json.load(f)
22 print(data)
23 # print(type(f.read()))
24 f.close()



pickle

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

 subprocess

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

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

模块有一个重要类: Popen



1 # Popen它的构造函数如下:
2  
3 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)




Fast Api 调用Session_python

Fast Api 调用Session_python_02

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


参数介绍


简单命令



1 # 此为linux下运行
 2 import subprocess
 3  
 4 a=subprocess.Popen('ls')#  创建一个新的进程,与主进程不同步
 5  
 6 print('>>>>>>>',a)#a是Popen的一个实例对象
 7  
 8 '''
 9 >>>>>>> <subprocess.Popen object at 0x10185f860>
10 __init__.py
11 __pycache__
12 log.py
13 main.py
14  
15 '''
16  
17 # subprocess.Popen('ls -l',shell=True)
18  
19 # subprocess.Popen(['ls','-l'])



subprocess.PIPE

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



1 import subprocess
2  
3 # subprocess.Popen('ls')
4 p=subprocess.Popen('ls',stdout=subprocess.PIPE)#结果跑哪去啦?
5  
6 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。



1 import subprocess
 2 
 3 #1
 4 # subprocess.call('ls',shell=True)
 5 '''
 6 hello.py
 7 ok.py
 8 web
 9 '''
10 # data=subprocess.call('ls',shell=True)
11 # print(data)
12 '''
13 hello.py
14 ok.py
15 web
16 '''
17 
18 #2
19 # subprocess.check_call('ls',shell=True)
20 
21 '''
22 hello.py
23 ok.py
24 web
25 '''
26 # data=subprocess.check_call('ls',shell=True)
27 # print(data)
28 '''
29 hello.py
30 ok.py
31 web
32 '''
33 # 两个函数区别:只是如果子进程返回的returncode不为0的话,将触发CalledProcessError异常
34 
35 
36 
37 #3
38 # subprocess.check_output('ls')#无结果
39 
40 # data=subprocess.check_output('ls')
41 # print(data)  #b'hello.py\nok.py\nweb\n'
42 
43 演示