python教程9、模块之sys,os,hashlib,random,time,datetime,logging,subprocess

python模块

  用一砣代码实现了某个功能的代码集合。 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。模块分为内建模块、自定义的模块、安装的第三方的模块

导入模块

Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用,如果想要使用模块,则需要导入。导入模块有一下几种方法:

1
2
3
4
import  module
from  module.xx.xx  import  xx
from  module.xx.xx  import  xx as rename
from  module.xx.xx  import  *

导入模块其实就是告诉Python解释器去解释那个py文件

  • 导入一个py文件,解释器解释该py文件
  • 导入一个包,解释器解释该包下的 __init__.py 文件

那么问题来了,导入模块时是根据那个路径作为基准来进行的呢?即:sys.path

1
2
3
4
5
6
7
>>>  import  sys
>>>  print (sys.path)
[' ', ' / home / tomcat / .pyenv / versions / 3.5 . 1 / lib / python35. zip ',
'/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5' ,
'/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5/plat-linux' ,
'/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5/lib-dynload' ,
'/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5/site-packages' ]

如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。

1
2
3
4
import  sys
import  os
project_path  =  os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(project_path) 

常用内置模块

内置模块是Python自带的功能,在使用内置模块相应的功能时,需要【先导入】再【使用】

一、sys

用于提供对Python解释器相关的操作:

1
2
3
4
5
6
7
8
9
sys.argv           命令行参数 List ,第一个元素是程序本身路径
sys.exit(n)        退出程序,正常退出时exit( 0 )
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的 Int
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操作系统平台名称
sys.stdin          输入相关
sys.stdout         输出相关
sys.stderror       错误相关

进度条示例:  

复制代码
import sys
import time

def view_bar(num,total):
    rate = num / total
    rate_num = int(rate * 100)
    r = '\r%s%d%%' % (">"*num,rate_num)
    sys.stdout.write(r)
    sys.stdout.flush()

if __name__ == '__main__':

    for i in range(0, 100):
        time.sleep(0.1)
        view_bar(i, 100)
复制代码

二、os

用于提供系统级别的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir( "dirname" )         改变当前脚本工作目录;相当于shell下cd
os.curdir                   返回当前目录: ( '.' )
os.pardir                   获取当前目录的父目录字符串名:( '..' )
os.makedirs( 'dir1/dir2' )    可生成多层递归目录
os.removedirs( 'dirname1' )   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir( 'dirname' )         生成单级目录;相当于shell中mkdir dirname
os.rmdir( 'dirname' )         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir( 'dirname' )       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()                 删除一个文件
os.rename( "oldname" , "new" )  重命名文件 / 目录
os.stat( 'path/filename' )    获取文件 / 目录信息
os.sep                      操作系统特定的路径分隔符,win下为 "\\",Linux下为" / "
os.linesep                  当前平台使用的行终止符,win下为 "\t\n" ,Linux下为 "\n"
os.pathsep                  用于分割文件路径的字符串
os.name                     字符串指示当前使用平台。win - > 'nt' ; Linux - > 'posix'
os.system( "bash command" )   运行shell命令,直接显示,不能保存执行结果<br>os.popen( "bash command" ).read()   运行shell命令,可以保存执行结果
os.environ                  获取系统环境变量
os.path.abspath(path)       返回path规范化的绝对路径
os.path.split(path)         将path分割成目录和文件名二元组返回
os.path.dirname(path)       返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)      返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)        如果path存在,返回 True ;如果path不存在,返回 False
os.path.isabs(path)         如果path是绝对路径,返回 True
os.path.isfile(path)        如果path是一个存在的文件,返回 True 。否则返回 False
os.path.isdir(path)         如果path是一个存在的目录,则返回 True 。否则返回 False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)      返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)      返回path所指向的文件或者目录的最后修改时间

三、hashlib

用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import  hashlib
  
# ######## md5 ########
hash  =  hashlib.md5()
# help(hash.update)
hash .update(bytes( 'admin' , encoding = 'utf-8' ))
print ( hash .hexdigest())
print ( hash .digest())
  
  
######## sha1 ########
  
hash  =  hashlib.sha1()
hash .update(bytes( 'admin' , encoding = 'utf-8' ))
print ( hash .hexdigest())
  
# ######## sha256 ########
  
hash  =  hashlib.sha256()
hash .update(bytes( 'admin' , encoding = 'utf-8' ))
print ( hash .hexdigest())
  
  
# ######## sha384 ########
  
hash  =  hashlib.sha384()
hash .update(bytes( 'admin' , encoding = 'utf-8' ))
print ( hash .hexdigest())
  
# ######## sha512 ########
  
hash  =  hashlib.sha512()
hash .update(bytes( 'admin' , encoding = 'utf-8' ))
print ( hash .hexdigest())

以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。  

扫描二维码关注公众号,回复: 4478078 查看本文章
1
2
3
4
5
6
7
import  hashlib
  
# ######## md5 ########
  
hash  =  hashlib.md5(bytes( '898oaFs09f' ,encoding = "utf-8" ))
hash .update(bytes( 'admin' ,encoding = "utf-8" ))
print ( hash .hexdigest())

四、random

1
2
3
4
5
6
7
8
9
10
11
12
import  random
  
print (random.random())               # 生成0-1之间的随机小数
print (random.randint( 1 20 ))        #生成1到20的整数包括20
print  random.uniform( 10 20 )      #生成10到20之间的浮点数
print (random.randrange( 1 10 ))   #生成1到10的证书不包括10,第3个参数可以指定步长
print (random.choice([ "JGood" "is" "a" "handsome" "boy" ]))  # 从序列中随机选一个数
 
# 每次对序列随机排序
=  [ "Python" "is" "powerful" "simple" ]
random.shuffle(p)
print (p)

随机验证码

复制代码
import random

li = []
for i in range(6):
    r = random.randint(0, 4)
    if r == 2 or r == 4:
        num = random.randrange(0, 10)
        li.append(str(num))
    else:
        temp = random.randrange(65,91)
        c = chr(temp)
        li.append(c)

result = "".join(li)
print(result)
复制代码
一些例子

五、time&datetime

时间相关的操作,时间有三种表示方式:

  • 时间戳                1970年1月1日之后的秒,即:time.time()
  • 格式化的字符串    2014-11-11 11:11,    即:time.strftime('%Y-%m-%d')
  • 结构化时间          元组包含了:年、日、星期等... time.struct_time    即:time.localtime()

time

1
2
3
4
5
6
7
8
9
10
11
12
13
import  time
 
print (time.clock())     #返回处理器时间,3.3开始已废弃
print (time.process_time())  #返回处理器时间,3.3开始已废弃<br>
print (time.time())     #返回当前系统时间戳输出:1471161757.5214906
print (time.ctime())    #输出字符串格式时间:Sun Aug 14 16:04:02 2016 ,当前系统时间
print (time.ctime(time.time() - 86640 ))    #将时间戳转为字符串格式<br>print(time.gmtime())  #获取结构化时间
print (time.gmtime(time.time() - 86640 ))   #将时间戳转换成struct_time格式
print (time.localtime(time.time() - 86640 ))  #将时间戳转换成struct_time格式,但返回的本地时间
print (time.mktime(time.localtime()))  #与time.localtime()功能相反,将struct_time格式转回成时间戳格式
time.sleep( 4 )   #睡上4秒
print (time.strftime( "%Y-%m-%d %H:%M:%S" ,time.gmtime()) )  #将struct_time格式转成指定的字符串格式
print (time.strptime( "2016-01-28" , "%Y-%m-%d" ) )  #将字符串格式转换成struct_time格式

datetime

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import  datetime
 
print (datetime.date.today())  #输出格式 2016-01-26
print (datetime.date.fromtimestamp(time.time() - 864400 ) )   #2016-01-16 将时间戳转成日期格式
current_time  =  datetime.datetime.now()  #
print (current_time)    #输出2016-01-26 19:04:30.335935
print (current_time.timetuple())   #返回struct_time格式
  
#datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])
print (current_time.replace( 2014 , 9 , 12 ))   #输出2014-09-12 19:06:24.074900,返回当前时间,但指定的值将被替换
  
str_to_date  =  datetime.datetime.strptime( "21/11/06 16:30" "%d/%m/%y %H:%M" #将字符串转换成日期格式
new_date  =  datetime.datetime.now()  +  datetime.timedelta(days = 10 #比现在加10天
new_date  =  datetime.datetime.now()  +  datetime.timedelta(days = - 10 #比现在减10天
new_date  =  datetime.datetime.now()  +  datetime.timedelta(hours = - 10 #比现在减10小时
new_date  =  datetime.datetime.now()  +  datetime.timedelta(seconds = 120 #比现在+120s
print (new_date)
View Code

六、logging模块  

很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug()info()warning()error() and critical() 5个级别,下面我们看一下怎么用。

日志级别对应的数字:

1
CRITICAL  =  50    ERROR  =  40    WARNING  =  30    INFO  =  20    DEBUG  =  10    NOTSET  =  0

日志记录格式:

%(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用户输出的消息

1、单文件日志

1
2
3
4
5
6
7
8
9
10
11
12
13
import  logging
 
logging.basicConfig(level = logging.DEBUG,
                     format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s' ,
                     datefmt = '%Y-%m-%d %H:%M:%S %p' ,
                     filename = 'test.log' ,
                     filemode = 'w' )
 
logging.debug( 'debug message' )
logging.info( 'info message' )
logging.warning( 'warning message' )
logging.error( 'error message' )
logging.critical( 'critical message' )

2、多文件日志

对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
import  logging
 
#获取日志器对象
logger  =  logging.getLogger( 'TEST-LOG' )   # 返回一个logger对象,没有指定的话默认是root logger
logger.setLevel(logging.DEBUG)   #设置全局日志级别
 
#定义屏幕控制器把日志输出屏幕
ch  =  logging.StreamHandler()  
ch.setLevel(logging.DEBUG)    # 输出屏幕的日志级别
formatter  =  logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
ch.setFormatter(formatter)    # 给输出屏幕的日志设置日志格式
logger.addHandler(ch)         # 将设定好的控制器添加到日志器中
 
#定义文件控制器把日志输出文件
fh  =  logging.FileHandler( "access.log"
fh.setLevel(logging.WARNING)   #设置输出文件的日志级别
formatter1  =  logging.Formatter( '%(asctime)s - %(levelname)s - %(message)s' )
fh.setFormatter(formatter1)    # 给输出文件的日志设置日志格式
logger.addHandler(fh)          # 将设定好的控制器添加到日志器中
 
logger.debug( 'debug message' )
logger.info( 'info message' )
logger.warn( 'warn message' )
logger.error( 'error message' )
logger.critical( 'critical message' )

注意:局部日志级别只有大于全局日志级别才会记录  

七、subprocess模块   

可以执行shell命令的相关模块和函数有:

  • os.system()   直接使用shell命令,不能保存运行的结果
  • os.spawn*    
  • os.popen().read()  直接使用shell命令,可以保存运行的结果
  • commands.*  python3.x已经废除
  • subprocess

1、os.system()

1
2
3
4
5
>>>  import  os
>>> os.system( 'ls' )
a.py   b.py   Desktop  myenv35  PycharmProjects  workplace
a.txt  b.txt  myenv27   pass .py  scripts
0

2、os.popen().read()  

1
2
3
4
5
6
7
>>>  import  os
>>> fi  =  os.popen( 'ls' ).read()
>>>  print (fi)
a.py
a.txt
b.py
b.txt

3、commands(在python2.x中执行)

1
2
3
4
5
6
7
8
9
10
11
>>>  import  commands
>>> result  =  commands.getoutput( 'ls' )
>>>  print (result)
a.py
a.txt
b.py
b.txt
 
>>> result1  =  commands.getstatusoutput( 'ls' )
>>>  print (result1)
( 0 'a.py\na.txt\nb.py\nb.txt\nDesktop\nmyenv27\nmyenv35\npass.py\nPycharmProjects\nscripts\nworkplace' )

4、subprocess  

subprocess.call()  执行命令,返回状态码,shell=False,第一个参数必须是列表,shell=True,第一个参数就直接输入命令即可

1
2
>>> ret  =  subprocess.call([ "ls" "-l" ], shell = False )<br>或:
>>> ret  =  subprocess.call( "ls -l" , shell = True )

subprocess.check_call() 执行命令,如果执行状态码是 0 ,则返回0,否则抛异常

1
2
>>> ret  =  subprocess.check_call([ "ls" "-l" ],shell = False )<br>>>>  print (ret)
>>> ret  =  subprocess.check_call( "exit 1" , shell = True )<br>>>>  print (ret)

subprocess.check_output() 执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常,注意这里返回的是字节类型,需要转换

1
2
>>> ret  =  subprocess.check_output([ "echo" "Hello World!" ],shell = False )<br>>>>  print ( str (ret,encoding = 'utf-8' ))<br>或
>>> ret  =  subprocess.check_output( "exit 1" , shell = True )<br>>>>  print ( str (ret,encoding = 'utf-8' ))

subprocess.run()  python3.5新加的功能,代替os.system,os.spawn

1
2
3
4
5
6
7
8
9
10
>>>  import  subprocess
 
>>> subprocess.run([ "ls" "-l" ])
total  56
- rw - rw - r - -  1  tomcat tomcat     61   8 月  11  23 : 27  a.py
- rw - rw - r - -  1  tomcat tomcat  12929   8 月   8  18 : 03  a.txt
CompletedProcess(args = [ 'ls' '-l' ], returncode = 0 )
 
>>> subprocess.run([ "ls" "-l" "/dev/null" ], stdout = subprocess.PIPE)
CompletedProcess(args = [ 'ls' '-l' '/dev/null' ], returncode = 0 , stdout = b 'crw-rw-rw- 1 root root 1, 3  8\xe6\x9c\x88 11 09:27 /dev/null\n' )

subprocess.Popen()  用于执行复杂的系统命令,是上面方法的底层实现

调用subprocess.run(...)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:

1
2
=  subprocess.Popen( "find ~/ -size +1000 -exec ls -shl {} \;" ,shell = True ,stdout = subprocess.PIPE)
print (p.stdout.read())

参数:

  • args:shell命令,可以是字符串或者序列类型(如:list,元组)
  • bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
  • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
  • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
  • close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
  • 所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
  • shell:同上
  • cwd:用于设置子进程的当前目录,相当于shell中cd进入当前目录
  • env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
  • universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
  • startupinfo与createionflags只在windows下有效
  • 将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

终端输入的命令分为两种:

  • 输入即可得到输出,如:ifconfig
  • 输入进行某环境,依赖再输入,如:python

(1)输入即可得到输出  

1
2
3
4
5
import  subprocess
 
obj  =  subprocess.Popen([ "mkdir" , "test" ],cwd = '/tmp/' ,)
或者
obj1  =  subprocess.Popen( "mkdir test1" , shell = True , cwd = '/tmp/' ,)

(2)输入进行某环境,依赖再输入,通过输入,输出,错误管道,输入数据,获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import  subprocess
 
obj  =  subprocess.Popen([ "python" ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True )
obj.stdin.write( "print(1)\n" )
obj.stdin.write( "print(2)" )
obj.stdin.close()
 
cmd_out  =  obj.stdout.read()
obj.stdout.close()
cmd_error  =  obj.stderr.read()
obj.stderr.close()
 
print (cmd_out)
print (cmd_error)
 
或者
obj  =  subprocess.Popen([ "python" ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True )
obj.stdin.write( "print(1)\n" )
obj.stdin.write( "print(2)" )
 
out_error_list  =  obj.communicate()
print (out_error_list)
 
或者
obj  =  subprocess.Popen([ "python" ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True )
 
out_error_list  =  obj.communicate( 'print("hello")' )
print (out_error_list)

猜你喜欢

转载自www.cnblogs.com/stssts/p/10109619.html