python学习—Day20—模块:logging、os、command、sys

logging的使用:

日志是我们排查问题的关键利器,写好日志记录,当我们发生问题时,可以快速定位代码范围进行修改,python有给开发者们提供好的日志模块,:logging

日志级别有五个:默认是info及以上。debug日志会打印所有日志,产生很多日志

import logging				\\从上往下,日志级别逐渐升高

logging.debug('this is debug message.')
logging.info('this is info message.')
logging.warning('this is warning message.')
logging.error('this is error message.')
logging.critical('this is critical message.')
WARNING:root:this is warning message.
ERROR:root:this is error message.
CRITICAL:root:this is critical message.



import logging


logging.basicConfig(level=__debug__, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',datefmt=' %Y/%m/%d %H:%M:%S', filename='xiao.log', filemode='w')
logger = logging.getLogger(__name__)	\\这里换成logger = logging.getLogger()最终输出没有区别。实际区别看下面注解
logging.warning('this is warning message.')
logging.error('this is error message.')
logging.critical('this is critical message.')
根据上面logging.basicConfig中定义的filename,会将日志打印到那个文件中。

各命令字详解:

level: 设置日志级别,默认为logging.WARNING

filename: 指定日志文件名。

filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'

format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:

%(levelname)s: 打印日志级别名称

 %(filename)s: 打印当前执行程序名

 %(funcName)s: 打印日志的当前函数

 %(lineno)d: 打印日志的当前行号

 %(asctime)s: 打印日志的时间

 %(thread)d: 打印线程ID

 %(process)d: 打印进程ID

 %(message)s: 打印日志信息

datefmt: 指定时间格式,同time.strftime()

stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略

logging.getLogger([name]):创建一个日志对象

输出具体情况为:

2017/11/10 10:27:56 demo_logging.py[line:20] WARNING this is warning message.
2017/11/10 10:27:56 demo_logging.py[line:21] ERROR this is error message.
2017/11/10 10:27:56 demo_logging.py[line:22] CRITICAL this is critical message.
并且,命令行:logger = logging.getLogger(__name__)中的(__name__)

返回一个logger实例,如果没有指定name,返回rootlogger。只要name相同,返回的logger实例都是同一个而且只有一个,即name和logger实例是一一对应的。这意味着,无需把logger实例在各个模块中传递。只要知道name,就能得到同一个logger实例。

logging.getLogger(__name__) 在上述实例中__name__就指的是__main__。


os模块的使用:

import os
print(os.name)
查看操作系统类型:

windows系统,返回值为:nt

linux系统,返回值为:posix


系统命令的操作:

print(os.system('ipconfig'))	\\在win系统上面操作ipconfig命令,返回类型为int
context = os.popen('ipconfig').read() \\这里将返回值处理为文件,可以进行查找匹配等操作
print(context)
print(context.find('192.168.172.1'))	\\返回该字符串所在位置的字节数

解释:

该代码调用了windows系统的ipconfig命令,ipconfig是用来查看windows系统ip的。os.system(‘ifconfig’)只会调用系统的命令,但是当我们需要获得系统命令最后的执行结果的时候该怎么办呢?

这时候我们就用os.popen方法,os.popen()返回的是一个file对象,我们可以通过file.read()来获得最后系统命令最终的结果

对于os模块的操作更多的操作可以使用  print(dir(os))   获取查看


文件和目录的操作:

import os
print(os.getcwd())		\\获得路径

os.chdir('d:')
print(os.getcwd())
os.chdir(r'C:\Users\module')
print(os.getcwd())		\\当前目录切换到D目录然后切换回来再查看

print(os.listdir(os.getcwd()))	\\列出当前目录的文件

print(os.listdir('C:\Python27'))	\\列出指定目录下的文件

os.mkdir('abc')			\\当前目录创建指定目录

os.removedirs('./abc')		\\删除指定目录。os.remove('1.txt')删除当前目录下的文件,文件不存在会报错

print(os.linesep)			\\打印操作系统分隔符(linux:\n;windows:\r\n;mac:\r)

print(os.path.join(os.getcwd(), 'buyaocunzai.txt'))	\\join就是用于拼接,文件可以不存在

print(os.path.islink(os.getcwd()))				\\返回就是false,三引号里面是解释
"""Test for symbolic link.
On WindowsNT/95 and OS/2 always returns false
"""

print(os.path.join(os.getcwd(), 'bucunzai.txt'))		\\只拼接,并不创建

path1 = os.path.join(os.getcwd(), 'meiyou.txt')		
print(os.path.split(path1))				\\把最后文件和目录分开

print(os.path.splitdrive(path1))				\\把最初目录和后面分开

print(os.path.splitext(path1))				\\把目录和后缀名分开

if not os.path.exists('./abc'):				\\判断目录是否存在,不存在则创建
    os.mkdir('./abc')

print(os.path.dirname(r'C:\Users\module\bucunzai.txt'))	\\获得bucunzai.txt文件的目录
C:\Users\module
D:\
C:\Users\module
['abc.txt', 'adatetime.py', 'demo1', 'demo_logging.py', 'demo_os.py', 'text.py', 'timezhuanhuan.py']
['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'pythonw.exe', 'README.txt', 'Scripts', 'tcl', 'Tools', 'w9xpopen.exe']

\\这里是打印的分隔符


C:\Users\module\buyaocunzai.txt
False
C:\Users\module\bucunzai.txt
('C:\\Users\\module', 'meiyou.txt')
('C:', '\\Users\\module\\meiyou.txt')
('C:\\Users\\module\\meiyou', '.txt')
C:\Users\module

解释:

1,  os.getcwd()   获得目录的当前系统程序工作路劲

2,  os. chdir(‘目标目录’) 切换到目标目录

3,  os.listdir(‘字符串目录’)    列出字符串目录下的所有文件

4,  os.mkdir('目录')  创建目录

5,  os.remove('1.txt')       删除文件,文件不存在时会报错

6,  os.linesep     打印操作系统的分隔符,linux系统的分隔符\n,windows系统的分隔符\r\n,mac系统的分隔符\r

7,  os.path.join(os.getcwd(), 'aaa', ‘bbb’, ‘ccc’) 拼接出来多级目录:E:\test\aaa\bbb\ccc

8,  os.path.exists(‘目录’) 判断目录是否存在

9,  os.path.split(‘文件或者目录’) 把最后的一个目录或者文件和前面的目录分开,返回一个tuple

10,os.path.splitext(‘文件’)    把文件的后缀名和前面分开,返回一个tuple

os.fork()


commands模块:只使用在linux的shell模式下

python学习—Day20—模块:logging、os、command、sys

In [1]: import commands

In [2]: cmd = 'ls /home'

In [3]: result = commands.getoutput(cmd)

In [4]: print(type(result))
<type 'str'>

In [5]: print(result)
nagios
xiaojingjing

commands.getoutput的返回值只有返回结果,没法进行判断执行结果是否正确


n [13]: cmd = 'ps -ef'

In [14]: status, result= commands.getstatusoutput(cmd)

In [15]: print(type(status))
<type 'int'>

In [16]: print(type(result))
<type 'str'>

In [17]: print(status)
0

commands.getstatusoutput()的返回值是一个tuple类型;第一个值接受返回状态码,返回类型是一个int类型,如果返回值是0说明执行正常,如果非0则说明结果异常;第二个值接受返回结果,返回结果是一个str类型.。


sys模块:

sys.argv[n]可以获取到python脚本后面传进去的参数。

import sys

if __name__=='__main__':
    print('sys.argv[0] = {0}'.format(sys.argv[0]))
    print('sys.argv[1] = {0}'.format(sys.argv[1]))
    print('sys.argv[2] = {0}'.format(sys.argv[2]))
sys.argv[0] = C:/Users/module/demo_sys.py
sys.argv[1] = -i
sys.argv[2] = text.py

这里是通过取python执行时后面的两个参数,类似与shell执行时的(bash 1.sh $1 $2)在pycharm中,需要在run的configure中进行配置,否则报错。


 sys.stdin\stdout\stderr

功能:stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们

print('print shuchu moren you huanhang')
sys.stdout.write('hello xiaojingjing')
print('***###meiyou huanhang####hello world')
name = raw_input('Please input your name:')	\\sys.stdout与 print
print('hello' + name)
address = sys.stdin.readline()			\\sys.stdin与 raw_input
print(address)
hello xiaojingjing***###meiyou huanhang####hello world

"""上面输出的原因:

当我们在 Python 中打印对象调用 print obj 时候,事实上是调用了sys.stdout.write(obj+'\n'),print 将你需要的内容打印到了控制台,然后追加了一个换行符,print 会调用 sys.stdout 的 write 方法

"""

Please input your name:xiaojingjing
helloxiaojingjing
hello world
hello world


捕获sys.exit(n)调用

功能:执行到主程序末尾,解释器自动退出,但是如果需要中途退出程序,可以调用sys.exit函数,带有一个可选的整数参数返回给调用它的程序,表示你可以在主程序中捕获对sys.exit的调用。(0是正常退出,其他为异常)

def hello():
    print('hello world')
sys.exitfunc = hello
print('start')
sys.exit(1)
print('end')
start
hello world

f = open('1.log', 'wb')
sys.stdout = f
print('aaaaa')
print('hello world')
f.close()			
生成一个1.log的文件,文件内容:

aaaaa
hello world

解释:

1,  设置sys.exitfunc函数,及当执行sys.exit(1)的时候,调用exitfunc函数

2,  sys.exit(1)后面的内容就不会执行了,因为程序已经退出。