python之模块

目录

1、sys模块

2、os模块

3、subprocess模块

4、hashlib模块

5、random模块

6、re模块

7、序列化之json模块 、 pickle模块 和 shelve模块

8、configparser模块

9、xml模块

10、requests模块

11、logging模块

12、shutil模块

13、paramiko模块

14、时间之time模块 和 datetime模块

15、collections模块

 

1、sys模块

(1)安装

  内置模块

  import sys

(2)使用说明

sys.argv  # 实现从程序外部向程序传递参数。
sys.exit([arg])  # 程序中间的退出,arg=0为正常退出。
sys.getdefaultencoding()  # 获取系统当前编码,一般默认为ascii。
sys.setdefaultencoding()  # 设置系统默认编码,执行dir(sys)时不会看到这个方法,在解释器中执行不通过,可以先执行reload(sys),在执行 setdefaultencoding('utf8'),此时将系统默认编码设置为utf8。(见设置系统默认编码 )
sys.getfilesystemencoding()  # 获取文件系统使用编码方式,Windows下返回'mbcs',mac下返回'utf-8'.
sys.path  # 获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到。
sys.stdin,sys.stdout,sys.stderr  # stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们
sys.maxsize  # 获取系统最大size
sys.platform  # 获取当前系统平台。
sys.version  # 获取python版本
sys.builtin_module_names  # 返回一个列表,包含内建模块的名字
sys.modules  # 返回一个字典,包含模块名字
sys模块

(3)验证

待补充

(4)参考

官网

sys:https://docs.python.org/2/library/sys.html

2、os模块

(1)安装

  内置模块

  import os

(2)使用说明

os.getcwd() #获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")  #改变当前脚本工作目录;相当于shell下cd
os.curdir  #返回当前目录: ('.')
os.pardir  #获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')    #可生成多层递归目录
os.removedirs('dirname1')   # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')   # 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() # 删除一个文件
os.rename("oldname","newname") # 重命名文件/目录
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命令,直接显示
os.environ  #获取系统环境变量
os.path.abspath(path)  #返回path规范化的绝对路径
os.path.split(path)  #将path分割成目录和文件名二元组返回
os.path.splitext()  # 分离文件名和扩展名
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所指向的文件或者目录的最后修改时间
os.exit()  # 退出当前进程
os.path.getsize(filename)  # 返回文件或文件夹大小,与os.stat(filename).st_size
os模块

(3)验证

>>> os.getcwd()  # 查看当前目录
'C:\\Python36'
>>> os.chdir("Lib")  # 换路径
>>> os.getcwd()  # 换路径成功
'C:\\Python36\\Lib'
>>> os.curdir
'.'
>>> os.pardir
'..'
>>> os.chdir('..')  # 返回
>>> os.getcwd()
'C:\\Python36'
>>> os.makedirs("test1/test2")  # 创建文件夹,可创建多层递归目录
>>> os.chdir("test1/test2")
>>> os.getcwd()  # 创建成功
'C:\\Python36\\test1\\test2'
>>> os.chdir('..')  # 返回
>>> os.getcwd()
'C:\\Python36\\test1'
>>> os.removedirs('test2')  # 删除文件夹
>>> os.chdir('test2')  # 已成功删除
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    os.chdir('test2')
FileNotFoundError: [WinError 2] 系统找不到指定的文件。: 'test2'
>>>os.mkdir('dirname')  # 创建文件夹
>>> os.chdir('dirname')
>>> os.getcwd()  # 创建成功
'C:\\Python36\\test1\\dirname'
>>> os.chdir('..')
>>> os.getcwd()
'C:\\Python36\\test1'
>>> os.rmdir('dirname')  # 删除文件夹
>>> os.chdir('dirname')
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    os.chdir('dirname')
FileNotFoundError: [WinError 2] 系统找不到指定的文件。: 'dirname'

>>> os.listdir()
[]
>>> os.chdir('..')
>>> os.listdir()  # 列出本文件夹的文件夹或文件
['a.txt', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python3.dll', 'python3.exe', 'python36.dll', 'pythonw.exe', 'qt.conf', 'README.txt', 'Scripts', 'selenium', 'tcl', 'test.bak', 'test.dat', 'test.dir', 'test1', 'Tools', 'vcruntime140.dll']
>>> os.chdir('test1')
>>> os.listdir()
['test.txt', 'test1.txt']
>>> os.remove('test.txt')  # 删除单个文件,注意是文件。
>>> os.listdir()  # 删除成功
['test1.txt']
>>> os.rename('test1.txt','test1_rename.txt')  # 修改文件夹或文件的名字
>>> os.listdir()
['test1_rename.txt']
>>> os.stat('test1_rename.txt')  # 查看文件夹或文件的信息
os.stat_result(st_mode=33206, st_ino=6755399441094891, st_dev=1315649016, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1500994476, st_mtime=1500994476, st_ctime=1500994476)
>>> os.sep  # 系统分隔符,windows是\\,linux是/
'\\'
>>> os.linesep  #输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
'\r\n'
>>> os.pathsep  #输出用于分割文件路径的字符串
';'
>>> os.name  #输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
'nt'
>>> os.system("bash command")  #运行shell命令,直接显示
1
>>> os.environ  #获取系统环境变量
environ({'ALLUSERSPROFILE': 'C:\\ProgramData', 'APPDATA': 'C:\\Users\\fat39\\AppData\\Roaming',  'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'FAT39-PC', 。。。略})
>>> os.path.abspath('test')  #返回path规范化的绝对路径
'C:\\Python36\\test1\\test'
>>> os.path.split('test')  #将path分割成目录和文件名二元组返回
('', 'test')
>>> os.path.splitext('test1_rename.txt')  # 分离文件名和扩展名
('test1_rename', '.txt')
>>> os.path.dirname('test\\test\\test\\test1_rename.txt') # 返回path的目录。其实就是os.path.split(path)的第一个元素
'test\\test\\test'
>>> os.path.dirname(r'test\test\test\test1_rename.txt') # 返回path的目录。其实就是os.path.split(path)的第一个元素
'test\\test\\test'
>>> os.path.basename(r'test\test\test\test1_rename.txt') # 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
'test1_rename.txt'
>>> os.path.exists(r'test\test\test\test1_rename.txt')  #如果path存在,返回True;如果path不存在,返回False
False
>>> os.path.exists(r'test1_rename.txt')  #如果path存在,返回True;如果path不存在,返回False
True
>>> os.path.isabs(r'test1_rename.txt')  #如果path是绝对路径,返回True
False
>>> os.path.isfile(r'test\test\test\test1_rename.txt')  #如果path是一个存在的文件,返回True。否则返回False
False
>>> os.path.isfile(r'test1_rename.txt')  #如果path是一个存在的文件,返回True。否则返回False
True
>>> os.path.isdir('test2')  #如果path是一个存在的目录,则返回True。否则返回False
True
>>> os.path.isdir('test1_rename.txt')  #如果path是一个存在的目录,则返回True。否则返回False
False
>>> os.path.join('test1','test2') # 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
'test1\\test2'
>>> os.path.getatime('test1_rename.txt')  #返回path所指向的文件或者目录的最后存取时间
1500994476.0000696
>>> os.path.getmtime('test1_rename.txt')  #返回path所指向的文件或者目录的最后存取时间
1500994476.0000696
>>> os.path.getsize('test1_rename.txt')  # 返回文件或文件夹大小,与os.stat(filename).st_size
0
>>> os.path.getsize('test2')  # 返回文件或文件夹大小,与os.stat(filename).st_size
0
验证

(4)参考

官网:

os:https://docs.python.org/2/library/os.html

3、subprocess模块

(1)安装

  内置模块

  ipmort subprocess

(2)使用说明

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

os.system
os.spawn*
os.popen* --废弃
popen2.* --废弃
commands.* --废弃,3.x中被移除

  以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能。
  subprocess的目的就是启动一个新的进程并且与之通信。

1 call  # 执行命令,返回状态码执行命令,并返回执行状态,其中shell参数为False时,命令需要通过列表的方式传入,当shell为True时,可直接传入命令。如果出现错误,不进行报错。
2 check_call  # 用法与subprocess.call()类似,区别是,当返回值不为0时,直接抛出异常。
3 check_output  # 用法与上面两个方法类似,区别是,如果当返回值为0时,直接返回输出结果,如果返回值不为0,直接抛出异常。需要说明的是,该方法在python3.x中才有。
4 subprocess.Popen()  # 用于执行复杂的系统命令
5 # subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
方法
 1 args:shell命令,可以是字符串或者序列类型(如:list,元组)
 2 bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
 3 stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
 4 preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
 5 close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
 6 所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
 7 shell:同上
 8 cwd:用于设置子进程的当前目录
 9 env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
10 universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
11 startupinfo与createionflags只在windows下有效
12 将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等 
Popen参数

 

child.wait()  # 等待子进程,类似于并发的join
child.poll() # 检查子进程状态
child.kill() # 终止子进程
child.send_signal() # 向子进程发送信号
child.terminate() # 终止子进程
ps: 子进程的PID存储在child.pid
子进程方法

 

(3)验证

  • call方法:父进程等待子进程执行命令,返回子进程执行命令的状态码,如果出现错误,不进行报错。
  • check_call方法:父进程等待子进程执行命令,返回执行命令的状态码,如果出现错误,进行报错【如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try…except…来检查】

call() 和 check_call()使用方法如下:

import subprocess

subprocess.call("ls -l", shell=True)
# subprocess.call(["ls", "-l"], shell=False)
'''
总用量 4
-rw-r--r--. 1 root root 98 4月   7 13:53 mp.py
drwxr-xr-x. 2 root root  6 4月   7 14:15 t1
0
'''

subprocess.call("ping www.baidu.com",shell=True)
'''
PING www.a.shifen.com (163.177.151.110) 56(84) bytes of data.
64 bytes from 163.177.151.110: icmp_seq=1 ttl=128 time=68.9 ms
64 bytes from 163.177.151.110: icmp_seq=2 ttl=128 time=36.5 ms

--- www.a.shifen.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 36.599/52.767/68.936/16.170 ms
0
'''

subprocess.call("ssh 1.1.1.40",shell=True)  # 通过call方法,直接从python跳转到ssh,python运行卡在这里
'''
root@1.1.1.40's password: 
Last login: Sat Apr  7 10:07:14 2018 from 1.1.1.39
[root@fat40 ~]# 
'''
# 以上,若执行成功,return值均为0
call方法(check_call用法一致,略),可运行系统命令,可直接从python跳转到ssh
  • check_output方法:父进程等待子进程执行命令,返回子进程向标准输出发送输出运行结果,检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try…except…来检查。
>>> res = subprocess.check_output('ls -l',shell=True)
>>> res  # 输出结果为bytes格式
b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 4\n-rw-r--r--. 1 root root 98 4\xe6\x9c\x88   7 13:53 mp.py\ndrwxr-xr-x. 2 root root  6 4\xe6\x9c\x88   7 14:15 t1\n'


>>> res = subprocess.check_output("asdfsadfsadf",shell=True)
/bin/sh: asdfsadfsadf: 未找到命令
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout
  File "/usr/local/lib/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'asdfsadfsadf' returned non-zero exit status 127.
>>> 
check_output方法
  •  Popen方法:实际上,subprocess模块中只定义了一个类: Popen。上面的几个函数都是基于Popen()的封装(wrapper)。从Python2.4开始使用Popen来创建进程,用于连接到子进程的标准输入/输出/错误中去,还可以得到子进程的返回值。这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程。与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block)。
################## mp.py ####################
import subprocess

child = subprocess.Popen(['ping','-c','4','www.baidu.com'])
print('hello')

[root@fat39 test]# python3 mp.py 
'''
hello
[root@fat39 test]# PING www.a.shifen.com (163.177.151.110) 56(84) bytes of data.
64 bytes from 163.177.151.110: icmp_seq=1 ttl=128 time=12.9 ms
64 bytes from 163.177.151.110: icmp_seq=2 ttl=128 time=37.4 ms
64 bytes from 163.177.151.110: icmp_seq=3 ttl=128 time=132 ms
64 bytes from 163.177.151.110: icmp_seq=4 ttl=128 time=687 ms

--- www.a.shifen.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 12.932/217.491/687.172/274.817 ms
'''



################## mp2.py ####################
import subprocess

child = subprocess.Popen(['ping','-c','4','www.baidu.com'])
child.wait()
print('hello')


[root@fat39 test]# python3 mp2.py
'''
PING www.a.shifen.com (163.177.151.110) 56(84) bytes of data.
64 bytes from 163.177.151.110: icmp_seq=1 ttl=128 time=443 ms
64 bytes from 163.177.151.110: icmp_seq=2 ttl=128 time=539 ms
64 bytes from 163.177.151.110: icmp_seq=3 ttl=128 time=109 ms
64 bytes from 163.177.151.110: icmp_seq=4 ttl=128 time=36.1 ms

--- www.a.shifen.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 36.177/282.106/539.028/213.638 ms
hello
'''
不等待子进程 与 子进程wait

 

import subprocess
child = subprocess.Popen('ls -l',shell=True,stdout=subprocess.PIPE)
print(child.stdout.read())
"""
b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 8\n-rw-r--r--. 1 root root 111 4\xe6\x9c\x88   7 14:51 mp2.py\n-rw-r--r--. 1 root root  98 4\xe6\x9c\x88   7 13:53 mp.py\ndrwxr-xr-x. 2 root root   6 4\xe6\x9c\x88   7 14:15 t1\n'
"""
"""
print(child.communicate())
(b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 8\n-rw-r--r--. 1 root root 111 4\xe6\x9c\x88   7 14:51 mp2.py\n-rw-r--r--. 1 root root  98 4\xe6\x9c\x88   7 13:53 mp.py\ndrwxr-xr-x. 2 root root   6 4\xe6\x9c\x88   7 14:15 t1\n', None)
"""

import subprocess
child1 = subprocess.Popen(['cat','/etc/passwd'],stdout=subprocess.PIPE)
child2 = subprocess.Popen(['grep','root'],stdin=child1.stdout,stdout=subprocess.PIPE)
print(child2.communicate())  # subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。注意:communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成
'''
(b'root:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin\n', None)
'''




import subprocess

obj = subprocess.Popen("python",shell=True, 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()
"""
1
2
"""
obj.stdout.close()
cmd_error = obj.stderr.read()
# 空白
obj.stderr.close()




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

out_error_list = obj.communicate()
print(out_error_list)
# ('1\n2\n', '')



import subprocess

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)
# ('hello\n', '')
子进程文本流控制 stdin|stdout|stderr

(4)参考

参考:

http://www.cnblogs.com/wupeiqi/articles/5501365.html

https://www.cnblogs.com/sunailong/p/5162748.html

4、hashlib模块

(1)安装

  内置模块

  import hashlib

(2)使用说明

Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。

什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。

摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。

摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。

  • python3,字符串需要encode("utf-8")
  • 内容太长时,可分次update,结果与一次过hash是一样的
  • 支持算法:md5, sha1, sha224, sha256, sha384, sha512

(3)验证

from hashlib import md5, sha1, sha224, sha256, sha384, sha512
from pprint import pprint

hash_funcs = [md5, sha1, sha224, sha256, sha384, sha512]


def hash_show(s):
    result = []
    for func in hash_funcs:  # 逐个算法
        s_hash_obj = func(s)
        s_hash_hex = s_hash_obj.hexdigest()
        result.append((s_hash_obj.name, s_hash_hex,  len(s_hash_hex)))
    return result


if __name__ == '__main__':
    s = 'hello python'.encode("utf-8")
    rs = hash_show(s)
    pprint(rs)
hashlib验证
#hashlib简单使用
def md5(arg):#这是加密函数,将传进来的函数加密
    md5_pwd = hashlib.md5(bytes('abd',encoding='utf-8'))
    md5_pwd.update(bytes(arg,encoding='utf-8'))
    return md5_pwd.hexdigest()#返回加密的数据
def log(user,pwd):#登陆时候时候的函数,由于md5不能反解,因此登陆的时候用正解
    with open('db','r',encoding='utf-8') as f:
        for line in f:
            u,p=line.strip().split('|')
            if u ==user and p == md5(pwd):#登陆的时候验证用户名以及加密的密码跟之前保存的是否一样
                return True
def register(user,pwd):#注册的时候把用户名和加密的密码写进文件,保存起来
    with open('db','a',encoding='utf-8') as f:
        temp = user+'|'+md5(pwd)
        f.write(temp)
 
i=input('1表示登陆,2表示注册:')
if i=='2':
    user = input('用户名:')
    pwd =input('密码:')
    register(user,pwd)
elif i=='1':
    user = user = input('用户名:')
    pwd =input('密码:')
    r=log(user,pwd)#验证用户名和密码
    if r ==True:
        print('登陆成功')
    else:
        print('登陆失败')
else:
    print('账号不存在')
结合hashlib的简单登录
from random import Random
from hashlib import md5


# 获取由4位随机大小写字母、数字组成的salt值
def create_salt(length=4):
    salt = ''
    chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
    len_chars = len(chars) - 1
    random = Random()
    for i in range(length):
        # 每次从chars中随机取一位
        salt += chars[random.randint(0, len_chars)]
    return salt


# 获取原始密码+salt的md5值
def create_md5(pwd, salt):
    md5_obj = md5()
    md5_obj.update(pwd + salt)
    return md5_obj.hexdigest()


# 原始密码
pwd = '20141124'
# 随机生成4位salt
salt = create_salt()
# 加密后的密码
md5 = create_md5(bytes(pwd,encoding="utf-8"), bytes(salt,encoding="utf-8"))


print(pwd)  # 20141124
print(salt)  # wAAn  # 随机
print(md5)  # 7b22cb2fed415097c942b130f210aac3

'''
数据库:
username  |  md5  |  salt
20141124  |  xxx  |  xxx
'''
加盐

(4)参考

https://blog.csdn.net/secret5/article/details/70150486

https://www.cnblogs.com/xiaobeibei26/p/6422012.html

5、random模块

(1)安装

  内置模块

  import random

(2)使用说明

random.seed(a=None, version=2)  # 初始化伪随机数生成器。如果未提供a或者a=None,则使用系统时间为种子。如果a是一个整数,则作为种子。
random.getstate()  # 返回一个当前生成器的内部状态的对象
random.setstate(state)  # 传入一个先前利用getstate方法获得的状态对象,使得生成器恢复到这个状态。
random.getrandbits(k)  # 返回range(0,2**k)之间的一个整数,相当于randrange(0,2**k)
random.randrange(stop)  # 返回range(0,stop)之间的一个整数
random.randrange(start, stop[, step])  # 返回range(start,stop)之间的一个整数,可加step,跟range(0,10,2)类似
random.randint(a, b)  # 返回range(a,b+1)之间的一个整数,等价于然的range(a,b+1)
random.choice(seq)  # 从非空序列seq中随机选取一个元素。如果seq为空则弹出 IndexError异常。
random.choices(population, weights=None, *, cum_weights=None, k=1)  # 3.6版本新增。从population集群中随机抽取K个元素(可重复)。weights是相对权重列表,cum_weights是累计权重,两个参数不能同时存在。
random.shuffle(x[, random])  # 随机打乱序列x内元素的排列顺序。只能针对可变的序列,对于不可变序列,请使用下面的sample()方法。
random.sample(population, k)  # 从population样本或集合中随机抽取K个不重复的元素形成新的序列。常用于不重复的随机抽样。返回的是一个新的序列,不会破坏原有序列。要从一个整数区间随机抽取一定数量的整数,请使用sample(range(10000000), k=60)类似的方法,这非常有效和节省空间。如果k大于population的长度,则弹出ValueError异常。
random.random()  # 返回一个介于左闭右开[0.0, 1.0)区间的浮点数
random.uniform(a, b)  # 返回一个介于a和b之间的浮点数。如果a>b,则是b到a之间的浮点数。这里的a和b都有可能出现在结果中。
random.triangular(low, high, mode)  # 返回一个low <= N <=high的三角形分布的随机数。参数mode指明众数出现位置。
random.betavariate(alpha, beta)  # β分布。返回的结果在0~1之间
random.expovariate(lambd)  # 指数分布
random.gammavariate(alpha, beta)  # 伽玛分布
random.gauss(mu, sigma)  # 高斯分布
random.lognormvariate(mu, sigma)  # 对数正态分布
random.normalvariate(mu, sigma)  # 正态分布
random.vonmisesvariate(mu, kappa)  # 卡帕分布
random.paretovariate(alpha)  # 帕累托分布
random.weibullvariate(alpha, beta)  # 威布尔分布
random模块

(3)验证

>>> random()                             # 随机浮点数:  0.0 <= x < 1.0
0.37444887175646646

>>> uniform(2.5, 10.0)                   # 随机浮点数:  2.5 <= x < 10.0
3.1800146073117523


>>> randrange(10)                        # 0-9的整数:

>>> randrange(0, 101, 2)                 # 0-100的偶数

>>> choice(['win', 'lose', 'draw'])      # 从序列随机选择一个元素
'draw'

>>> deck = 'ace two three four'.split()
>>> shuffle(deck)                        # 对序列进行洗牌,改变原序列
>>> deck
['four', 'two', 'ace', 'three']

>>> sample([10, 20, 30, 40, 50], k=4)    # 不改变原序列的抽取指定数目样本,并生成新序列
[40, 10, 50, 30]


>>> # 6次旋转红黑绿轮盘(带权重可重复的取样),不破坏原序列,weight[18,18,2]
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']

>>> # 德州扑克计算概率Deal 20 cards without replacement from a deck of 52 playing cards
>>> # and determine the proportion of cards with a ten-value
>>> # (a ten, jack, queen, or king).
>>> deck = collections.Counter(tens=16, low_cards=36)
>>> seen = sample(list(deck.elements()), k=20)
>>> seen.count('tens') / 20
0.15

>>> # 模拟概率Estimate the probability of getting 5 or more heads from 7 spins
>>> # of a biased coin that settles on heads 60% of the time.'H'的概率是0.6,“T”的概率是1-0.6
>>> trial = lambda: choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
>>> sum(trial() for i in range(10000)) / 10000
0.4169

>>> # Probability of the median of 5 samples being in middle two quartiles
>>> trial = lambda : 2500 <= sorted(choices(range(10000), k=5))[2]  < 7500
>>> sum(trial() for i in range(10000)) / 10000
0.7958
>>> from statistics import mean
>>> from random import choices

>>> data = 1, 2, 4, 4, 10
>>> means = sorted(mean(choices(data, k=5)) for i in range(20))  # mean是求平均
>>> print(f'The sample mean of {mean(data):.1f} has a 90% confidence '
      f'interval from {means[1]:.1f} to {means[-2]:.1f}')  # 这里的f用法
基本例子
import random
 
checkcode = ''
for i in range(4):
    current = random.randrange(0,4)
    if current != i:
        temp = chr(random.randint(65,90))
    else:
        temp = random.randint(0,9)
    checkcode += str(temp)
print(checkcode)
生成一个包含大写字母A-Z和数字0-9的随机4位验证码的程序
import random, string


def gen_random_string(length):
    # 数字的个数随机产生
    num_of_numeric = random.randint(1,length-1)
    # 剩下的都是字母
    num_of_letter = length - num_of_numeric
    # 随机生成数字
    numerics = [random.choice(string.digits) for i in range(num_of_numeric)]
    # 随机生成字母
    letters = [random.choice(string.ascii_letters) for i in range(num_of_letter)]
    # 结合两者
    all_chars = numerics + letters
    # 洗牌
    random.shuffle(all_chars)
    # 生成最终字符串
    result = ''.join([i for i in all_chars])
    return result

if __name__ == '__main__':
    print(gen_random_string(64))
生成指定长度字母数字随机序列的代码

(4)参考

参考:1、官网;2、别人的

6、re模块

https://www.cnblogs.com/fat39/p/9510441.html

7、序列化之json模块 、 pickle模块 和 shelve模块

什么是序列化

我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

python用于序列化的两个模块

  • json     用于【字符串】和 【python基本数据类型】 间进行转换
  • pickle   用于【python特有的类型】 和 【python基本数据类型】间进行转换

另,可使用内置方法eval(xxxxx),但效果有限。

7.1、json模块

(1)安装

  内置模块

  import json

(2)使用说明

json,Json模块提供了四个功能:dumps、dump、loads、load

dumps  # 将字典转换成字符串,转换后的字典中的元素是由双引号表示的
dump  # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
loads  # 将一个字符串转换成字典类型
load  # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
json

 

(3)验证

import json

dic={'k1':'v1','k2':'v2','k3':'v3'}  # dict类型

# 写dumps
with open("test.json","w") as f:
    str_dic = json.dumps(dic)  # str类型
    f.write(str_dic)  # f内容如下:{"k1": "v1", "k2": "v2", "k3": "v3"}

# 读loads
with open("test.json","r") as f:
    str_dic = f.read()  # str类型,内容是:  {"k1": "v1", "k2": "v2", "k3": "v3"}
    dic = json.loads(str_dic)  # dict类型,内容是:{"k1": "v1", "k2": "v2", "k3": "v3"}

# 写dump
dic2={'k4':'v4','k5':'v5','k6':'v6'}  # dict类型
with open("test2.json","w") as f:
    json.dump(dic2,f)  # f内容如下:{"k4": "v4", "k5": "v5", "k6": "v6"}

# 读loads
with open("test2.json","r") as f:
    res = json.load(f)   # dict类型,内容是{'k4': 'v4', 'k5': 'v5', 'k6': 'v6'}
json验证
################ JSONEncoder #############
import json
from datetime import datetime,date

class JsonCustomEncoder(json.JSONEncoder):
    def default(self, value):
        if isinstance(value, datetime):
            return value.strftime('%Y-%m-%d %H:%M:%S')  # 转换为字符串
        elif isinstance(value, date):
            return value.strftime('%Y-%m-%d')  # 转换为字符串
        else:
            return json.JSONEncoder.default(self, value)

dt = datetime.now()
d = date.today()

print(json.dumps(dt,cls=JsonCustomEncoder))  # "2018-04-06 09:52:03"
print(json.dumps(d,cls=JsonCustomEncoder))  # "2018-04-06"

################ JSONDecoder #############
简单验证,待完善
import json
dt = "2018-04-06 09:51:30"
d = "2018-04-06"

class JsonCustomDecoder(json.JSONDecoder):
    def decode(self,value):
        import time
        return time.strptime(value, "%Y-%m-%d %X")

print(json.loads(dt,cls=JsonCustomDecoder))  # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=6, tm_hour=9, tm_min=51, tm_sec=30, tm_wday=4, tm_yday=96, tm_isdst=-1)
自定义json cls
import json

v = {"k":"中国人"}

ret = json.dumps(v)  # 默认ensure_ascii=True,把中文也转为unicode
print(ret)  # {"k": "\u4e2d\u56fd\u4eba"}
ret = json.dumps(v,ensure_ascii=False)  # 不把中文转为unicode
print(ret)  # {"k": "中国人"}
中文转unicode(乱码) 涉及ensure_ascii

(4)参考

7.2、pickle模块

(1)安装

  内置模块

  import pickle

(2)使用说明

pickle支持所有python数据类型,pickle模块提供了四个功能:dumps、dump、loads、load,与json类型

(3)验证

import pickle

dic = {'k1':'v1','k2':'v2','k3':'v3'}

str_dic=pickle.dumps(dic)  # # bytes类型,内容是: b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04X\x02\x00\x00\x00k3q\x05X\x02\x00\x00\x00v3q\x06u.'
dic2 = pickle.loads(str_dic)  # dict类型,内容是: {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
with open("test2.pickle","wb") as f:  # b模式
    pickle.dump(dic,f)

with open("test2.pickle","rb") as f:  # b模式
    x=pickle.load(f)  # dict类型,内容是:{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}


import time
now = time.localtime()  # struct time
with open("test3.pickle","wb") as f:
    pickle.dump(now,f)

with open("test3.pickle","rb") as f:
    x = pickle.load(f)  # time类型,内容是: time.struct_time(tm_year=2018, tm_mon=4, tm_mday=6, tm_hour=10, tm_min=3, tm_sec=41, tm_wday=4, tm_yday=96, tm_isdst=0)
pickle验证

(4)参考

7.3、shelve模块

(1)安装

  内容模块

  import shelve

(2)使用说明

shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些。
shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似。

这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB

(3)验证

import shelve

f = shelve.open(r'shelve.txt')

########## 写 ############
f['stu1_info']={'name':'alex','age':'18'}
f['stu2_info']={'name':'alvin','age':'20'}
f['school_info']={'website':'oldboyedu.com','city':'beijing'}

f.close()


########## 读 ############
f = shelve.open(r'shelve.txt')
print(f.get("stu1_info")["age"])  # 18
shelve验证

(4)参考

8、configparser模块

(1)安装

  内置模块

  import configparser

(2)使用说明

源文件指定格式

# 注释1
;  注释2
 
[section1] # 节点
k1 = v1    #
k2:v2       #
 
[section2] # 节点
k1 = v1    #
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.sections()
print(ret)
获取所有节点
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.items('section1')
print(ret)
获取指定节点下所有的键值对
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.options('section1')
print(ret)
获取指定节点下所有的建
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
 
v = config.get('section1', 'k1')
# v = config.getint('section1', 'k1')
# v = config.getfloat('section1', 'k1')
# v = config.getboolean('section1', 'k1')
 
print(v)
获取指定节点下指定key的值
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
 
# 检查
has_sec = config.has_section('section1')
print(has_sec)
 
# 添加节点
config.add_section("SEC_1")
config.write(open('xxxooo', 'w'))
 
# 删除节点
config.remove_section("SEC_1")
config.write(open('xxxooo', 'w'))
检查、删除、添加节点
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
# 检查
has_opt = config.has_option('section1', 'k1')
print(has_opt)
 
# 删除
config.remove_option('section1', 'k1')
config.write(open('xxxooo', 'w'))
 
# 设置
config.set('section1', 'k10', "123")
config.write(open('xxxooo', 'w'))
检查、删除、设置指定组内的键值对

(3)验证

#-*- encoding: utf-8 -*-

import  configparser
# 1、conf = configparser.ConfigParser()
# 2、settings = configparser.ConfigParser(interpolation=ExtendedInterpolation())  # 读ini文件,初始化不一样,用法一样

test = \
'''
[db]
db_host = 127.0.0.1
db_port = 3306
db_user = root
db_pass = 123

[concurrent]
thread = 10
processor = 20
'''

test_dict = {
    "db":{
        "db_host":"127.0.0.1",
        "db_port":"3306",
        "db_user":"root",
        "db_pass":"123"
    },
    "concurrent":{
        "thread":"10",
        "processor":"20"
    },
    "lab":{
        "name":"tom",
        "password":"123"
    }
}

conf = configparser.ConfigParser()
conf.read("test.conf")  # 读取文件
# conf.read_string(test)  # 读取str,比如上面的test字段
# conf.read_dict(test_dict)  # 读取dict,比如上面的test_dict

db_option = conf.options("db")  # 读取option,相当于dict的key,['db_host', 'db_port', 'db_user', 'db_pass']
db_items = conf.items("db")  # 相当于dict的item,[('db_host', '127.0.0.1'), ('db_port', '3306'), ('db_user', 'root'), ('db_pass', '123')]
sec = conf.sections()  # 读取标题,['db', 'concurrent']
#---------------------------------------------------------------------------------

db_host = conf.get("db","db_host") # type str  127.0.0.1
db_port = conf.getint("db","db_port")  # type int  3306
db_user = conf.get("db","db_user")  # type str  root
db_pass = conf.get("db","db_pass")  # type str  123

concurrent_thread = conf.getint("concurrent","thread")  # type int  10
concurrent_processor = conf.getint("concurrent","processor")  # type int  20

#---------------------------------------------------------------------------------
conf.set("db", "db_pass", "test123")  # 修改section db 的db_pass,新值是test123
conf.set("db","db_test","test_db")  # 新增,与修改是一个用法

#---------------------------------------------------------------------------------
conf.add_section("abc")  # 增加section,abc
conf.set("abc","country","CN")  # 增加字段
conf.set("abc","time_zone","+8")

#---------------------------------------------------------------------------------
print(conf.has_section("db"))  # True
print(conf.has_section("abcdefg"))  # False
print(conf.has_option("abc","country"))  # True
print(conf.has_option("abc","abc_name"))  # False

#---------------------------------------------------------------------------------
new_dict = {
    "guest":{
        "name":"guest",
        "password":"123"
    }
}

conf.update(new_dict)  # 直接通过dict更新

#---------------------------------------------------------------------------------
with open("test1.conf","w") as f:
    conf.write(f)



"""
[db]
db_host = 127.0.0.1
db_port = 3306
db_user = root
db_pass = test123
db_test = test_db

[concurrent]
thread = 10
processor = 20

[abc]
country = CN
time_zone = +8

[guest]
name = guest
password = 123

"""

#---------------------------------------------------------------------------------

settings_ini = \
"""
[SectionOne]
Param1: Hello
Param2: World
 
[SectionTwo]
Param1: ${SectionOne:Param1} ${SectionOne:Param2}
 
[SectionThree]
Alpha: One
Bravo: Two
Charlie: ${Alpha} Mississippi
"""



settings = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())  # 用法同上
settings.read_string(settings_ini)

sec = settings.sections()  # ['SectionOne', 'SectionTwo', 'SectionThree']
SectionThree = settings.items("SectionThree")
print(SectionThree)  # [('alpha', 'One'), ('bravo', 'Two'), ('charlie', 'One Mississippi')]
configparser模块

(4)参考

9、xml模块

(1)安装

(2)使用说明

(3)验证

(4)参考

10、requests模块

https://www.cnblogs.com/fat39/p/9028551.html#tag1

11、logging模块

(1)安装

  内置模块

  import logging

(2)使用说明

logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为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用户输出的消息
配置参数
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
日志等级

另转了一篇logging模块文章:(转)一篇写的简明易懂的logging模块

补充:想改一下logging的方法如这里的info,但发现logging.getLogger(log_type)返回是一个实例对象,所以尝试了下面的方法,仅做记录。

# -*- coding:utf-8 -*-

from cl.conf import settings
import logging
import os


def test(system_log):
    class Test(type(system_log)):
        def info(self,*args,**kwargs):
            res = super(Test, self).info(*args,**kwargs)
            print("test info")
            return res
    return Test


def logger(log_type):
    logger = logging.getLogger(log_type)

    '''############# 增加了这一条 #############'''
    logger = test(logger)(log_type)
    '''############# 增加了这一条 #############'''

    logger.setLevel(settings.LOG_LEVEL)

    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(settings.LOG_LEVEL)

    # create file handler and set level to warning
    log_file = os.path.join(settings.LOG_FILES_DIR,settings.LOG_TYPES[log_type])
    fh = logging.FileHandler(log_file)
    fh.setLevel(settings.LOG_LEVEL)

    # create formatter
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # add formatter to ch and fh
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)

    # add ch and fh to logger
    logger.addHandler(ch)  #  #logger对象可以添加多个fh和ch对象
    logger.addHandler(fh)

    return logger



system_log = logger("system")
# system_log.info("haha")
print(test(system_log).__mro__)  # (<class '__main__.test.<locals>.Test'>, <class '__main__.test.<locals>.Test'>, <class 'logging.Logger'>, <class 'logging.Filterer'>, <class 'object'>)
改写了类的方法
# -*- coding:utf-8 -*-

from cl.conf import settings
import logging
import os
from logging import Logger

class NewLogger(Logger):
    def info(self, *args, **kwargs):
        res = super(NewLogger, self).info(*args, **kwargs)
        print("test info")
        return res

def test(system_log):
    class Test(type(system_log)):
        def info(self,*args,**kwargs):
            res = super(Test, self).info(*args,**kwargs)
            print("test info")
            return res
    return Test


def logger(log_type):
    # logger = logging.getLogger(log_type)
    logger = NewLogger(log_type)
    '''############# 增加了这一条 #############'''
    # logger = test(logger)(log_type)
    '''############# 增加了这一条 #############'''

    logger.setLevel(settings.LOG_LEVEL)

    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(settings.LOG_LEVEL)

    # create file handler and set level to warning
    log_file = os.path.join(settings.LOG_FILES_DIR,settings.LOG_TYPES[log_type])
    fh = logging.FileHandler(log_file)
    fh.setLevel(settings.LOG_LEVEL)

    # create formatter
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # add formatter to ch and fh
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)

    # add ch and fh to logger
    logger.addHandler(ch)  #  #logger对象可以添加多个fh和ch对象
    logger.addHandler(fh)

    return logger



system_log = logger("system")
system_log.info("haha")
# print(test(system_log).__mro__)  # (<class '__main__.test.<locals>.Test'>, <class '__main__.test.<locals>.Test'>, <class 'logging.Logger'>, <class 'logging.Filterer'>, <class 'object'>)
我擦,突然发现可以直接实例化Logger而不用logging.getLogger

 

(3)验证

实验一

import logging

logging.basicConfig(filename='log.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)

logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10, 'log')


'''
2018-04-11 22:50:11 PM - root - DEBUG -test1:  debug
2018-04-11 22:50:11 PM - root - INFO -test1:  info
2018-04-11 22:50:11 PM - root - WARNING -test1:  warning
2018-04-11 22:50:11 PM - root - ERROR -test1:  error
2018-04-11 22:50:11 PM - root - CRITICAL -test1:  critical
2018-04-11 22:50:11 PM - root - DEBUG -test1:  log
'''
最简单的实验

实验二 多个日志文件

# -*- coding:utf-8 -*-
import logging
# 定义文件
file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
file_1_1.setFormatter(fmt)

file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
fmt = logging.Formatter()
file_1_2.setFormatter(fmt)

# 定义日志
logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_1_1)
logger1.addHandler(file_1_2)


# 写日志
logger1.critical('1111')



############# l1.1.log ################
2018-04-11 22:52:29,330 - s1 - CRITICAL -test2:  1111


############# l1.2.log ################
1111
多个日志文件

实验三

# -*- coding:utf-8 -*-
import os
import logging

############### 可写入settings.py ###############
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
LOG_LEVEL = logging.INFO
LOG_TYPES = {
    'system': 'system.log',
    'interactive':"interactive.log"
}



def logger(log_type):
    # create logger
    logger = logging.getLogger(log_type)
    logger.setLevel(LOG_LEVEL)

    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(LOG_LEVEL)

    # create file handler and set level to warning
    log_file = "%s/log/%s" % (BASE_DIR, LOG_TYPES[log_type])
    fh = logging.FileHandler(log_file)
    fh.setLevel(LOG_LEVEL)

    # create formatter
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # add formatter to ch and fh
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)

    # add ch and fh to logger
    logger.addHandler(ch)  #  #logger对象可以添加多个fh和ch对象
    logger.addHandler(fh)

    return logger
logger.py
# -*- coding:utf-8 -*-

import logger

interact_log = logger.logger("interactive")
system_log = logger.logger("system")



############## 脚本开始 ##############
system_log.info("程序开始")


while True:
    cmd = input(">>:")
    print("执行命令,返回结果")
    if cmd.startswith("rm"):
        interact_log.warning(cmd)
    else:
        interact_log.info(cmd)

    if cmd == "exit":
        system_log.info("退出程序")
        exit()
core.py
########### interactive.log ###########
2018-04-11 22:36:32,417 - interactive - INFO - hi
2018-04-11 22:36:34,679 - interactive - INFO - ll
2018-04-11 22:36:38,597 - interactive - INFO - dsf
2018-04-11 22:36:41,887 - interactive - WARNING - rm -rf /
2018-04-11 22:37:07,331 - interactive - INFO - ok
2018-04-11 22:37:08,397 - interactive - INFO - exit

注:由于配置了StreamHandler,以上均在屏幕上显示出来

########### system.log ###########
2018-04-11 22:36:26,650 - system - INFO - 程序开始
2018-04-11 22:37:08,398 - system - INFO - 退出程序

注:由于配置了StreamHandler,以上均在屏幕上显示出来
结果

 

(4)参考

http://www.cnblogs.com/yuanchenqi/articles/6766020.html#_label5

http://www.cnblogs.com/wupeiqi/articles/5501365.html

12、shutil模块

(1)安装

  内置模块

  import shutil

(2)使用说明

shutil.copyfileobj(fsrc, fdst[, length])  # 将文件内容拷贝到另一个文件中
shutil.copyfile(src, dst)  # 拷贝文件
shutil.copymode(src, dst)  # 仅拷贝权限。内容、组、用户均不变
shutil.copystat(src, dst)  # 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copy(src, dst)  # 拷贝文件和权限
shutil.copy2(src, dst)  # 拷贝文件和状态信息
shutil.ignore_patterns(*patterns)  # 作为参数,传入下面的copytree。忽略某些字段的文件。
shutil.copytree(src, dst, symlinks=False, ignore=None)  # 递归的去拷贝文件夹
shutil.rmtree(path[, ignore_errors[, onerror]])  # 递归的去删除文件
shutil.move(src, dst)  # 递归的去移动文件,它类似mv命令,其实就是重命名。
shutil.make_archive(base_name, format,...)  # 创建压缩包并返回文件路径,例如:zip、tar
    base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    如:www                        =>保存至当前路径
    如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    format:    压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    root_dir:    要压缩的文件夹路径(默认当前目录)
    owner:    用户,默认当前用户
    group:    组,默认当前组
    logger:    用于记录日志,通常是logging.Logger对象
方法说明

(3)验证

1、copyfileobj
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
shutil.copyfileobj(open('old.xml','r'), open('new1.xml', 'a'))  # 在后面追加
'''
[root@fat40 shutil_test]# ll
总用量 16
-rw-r--r--. 1 root  root   42 4月   8 12:24 new1.xml
-rw-r--r--. 1 root  root   25 4月   8 12:24 new.xml
-rw-r--r--. 1 admin admin  25 4月   8 12:17 old.xml
-rw-r--r--. 1 root  root  141 4月   8 12:23 test.py
'''

2、copyfile
shutil.copyfile('old.xml', 'haha.xml')
'''
-rw-r--r--. 1 root  root   25 4月   8 12:28 haha.xml
'''

3、copymode
# shutil.copymode('old.xml', 'new.xml')  # 报错,因为没有该文件
shutil.copymode('old.xml', 'new2.xml')
'''
-rwxrwxrwx. 1 root  root    0 4月   8 12:33 new2.xml    # mode换了
-rwxrwxrwx. 1 admin admin  25 4月   8 12:17 old.xml
'''

4、copystat
shutil.copystat('old.xml', 'newnew.xml')
'''
-rwxrwxrwx. 1 root  root    0 4月   8 12:17 newnew.xml
-rwxrwxrwx. 1 admin admin  25 4月   8 12:17 old.xml

[root@fat40 shutil_test]# stat old.xml 
  文件:"old.xml"
  大小:25            块:8          IO 块:4096   普通文件
设备:fd00h/64768d    Inode:102072723   硬链接:1
权限:(0777/-rwxrwxrwx)  Uid:( 1001/   admin)   Gid:( 1001/   admin)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2018-04-08 12:17:53.843571572 +0800
最近更改:2018-04-08 12:17:03.979569888 +0800
最近改动:2018-04-08 12:33:53.440603988 +0800
创建时间:-


[root@fat40 shutil_test]# stat newnew.xml 
  文件:"newnew.xml"
  大小:0             块:0          IO 块:4096   普通空文件
设备:fd00h/64768d    Inode:102072720   硬链接:1
权限:(0777/-rwxrwxrwx)  Uid:(    0/    root)   Gid:(    0/    root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2018-04-08 12:17:53.843571572 +0800
最近更改:2018-04-08 12:17:03.979569888 +0800
最近改动:2018-04-08 12:41:51.862620149 +0800
创建时间:-
'''

5、copy
shutil.copy("old.xml","new.xml")
'''
-rwxrwxrwx. 1 root  root   25 4月   8 13:02 new.xml
-rwxrwxrwx. 1 admin admin  25 4月   8 12:17 old.xml
'''

6、copy2
shutil.copy2("old.xml","new.xml")
'''
[root@fat40 shutil_test]# stat new.xml 
  文件:"new.xml"
  大小:25            块:8          IO 块:4096   普通文件
设备:fd00h/64768d    Inode:102072721   硬链接:1
权限:(0777/-rwxrwxrwx)  Uid:(    0/    root)   Gid:(    0/    root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2018-04-08 13:02:38.419662258 +0800
最近更改:2018-04-08 12:17:03.979569888 +0800
最近改动:2018-04-08 13:05:25.222667893 +0800
创建时间:-
[root@fat40 shutil_test]# stat old.xml 
  文件:"old.xml"
  大小:25            块:8          IO 块:4096   普通文件
设备:fd00h/64768d    Inode:102072723   硬链接:1
权限:(0777/-rwxrwxrwx)  Uid:( 1001/   admin)   Gid:( 1001/   admin)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2018-04-08 13:02:38.419662258 +0800
最近更改:2018-04-08 12:17:03.979569888 +0800
最近改动:2018-04-08 12:33:53.440603988 +0800
创建时间:-
'''

7、ignore_patterns 和 copytree
shutil.copytree("a","new_folder",ignore=shutil.ignore_patterns("*.html","*.go"))  # 不复制html和go文件
'''
[root@fat40 shutil_test]# tree a
a
├── a.html
├── a.py
├── a.txt
└── b
    ├── b.c
    ├── b.go
    ├── b.html
    └── c
        ├── c.html
        ├── c.txt
        ├── c.zzz
        └── old.xml

2 directories, 10 files
[root@fat40 shutil_test]# tree new_folder/
new_folder/
├── a.py
├── a.txt
└── b
    ├── b.c
    └── c
        ├── c.txt
        ├── c.zzz
        └── old.xml

2 directories, 6 files
'''

8、rmtree
shutil.rmtree("new_folder")
'''
删除成功
'''

9、move
shutil.move("a","new_a")
'''
drwxr-xr-x. 3 root root  50 4月  11 10:10 new_a
'''

10、make_archive
ret = shutil.make_archive("hahaha","gztar",root_dir="new_a/b")
print(ret)
'''
root/shutil_test/hahaha.tar.gz
-rw-r--r--. 1 root root 313 4月  11 10:23 hahaha.tar.gz
'''

ret = shutil.make_archive("newfolder/hahaha","gztar",root_dir="new_a/b")
print(ret)

'''
/root/shutil_test/hahaha.tar.gz
[root@fat40 shutil_test]# tree newfolder/
newfolder/
└── hahaha.tar.gz

'''
shutil的验证
import zipfile

# 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()

# 解压
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall()
z.close()




import tarfile

# 压缩
tar = tarfile.open('your.tar','w')
tar.add('a/b/bbs2.log', arcname='bbs2.log')
tar.add('a/b/cmdb.log', arcname='cmdb.log')
tar.close()

# 解压
tar = tarfile.open('your.tar','r')
tar.extractall()  # 可设置解压地址
tar.close()
补充:shutil压缩是调用ZipFile和TarFile

(4)参考

http://www.cnblogs.com/wupeiqi/articles/5501365.html

13、paramiko模块

(1)安装

pip3 install pycrypto  # 由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto
pip3 install paramiko

(2)使用说明

(3)验证

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("1.1.1.39",22,"root","toor")
cmd = input(">>:")
stdin,stdout,stderr = ssh.exec_command(cmd)
print((stdout.read()+stderr.read()).decode("utf-8"),)
ssh.close()
执行命令---用户名+密码
private_key_path = r'C:\Users\fat39\.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("1.1.1.39",22,"root",key)
cmd = input(">>:")
stdin,stdout,stderr = ssh.exec_command(cmd)
print((stdout.read()+stderr.read()).decode("utf-8"),)
ssh.close()
执行命令--秘钥
################ 上传 ###################
t = paramiko.Transport(("1.1.1.39",22))
t.connect(username="root",password="toor")
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put("paramiko-master.zip","/home/fat39/paramiko-master.zip")
t.close()


################ 下载 ###################

t = paramiko.Transport(("1.1.1.39",22))
t.connect(username="root",password="toor")
sftp = paramiko.SFTPClient.from_transport(t)
sftp.get("/home/fat39/paramiko-master.zip","haha.zip")
t.close()
上传/下载文件--用户名+密码
############## 上传 ################
private_key_path = r'C:\Users\fat39\.ssh\id_rsa'
key = paramiko.RSAKey.from_private_key_file(private_key_path)
t = paramiko.Transport(('1.1.1.39',22))
t.connect(username='root',pkey=key)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put('paramiko-master.zip','/home/fat39/haha.zip')


############## 下载 ################
private_key_path = r'C:\Users\fat39\.ssh\id_rsa'
key = paramiko.RSAKey.from_private_key_file(private_key_path)
t = paramiko.Transport(('1.1.1.39',22))
t.connect(username='root',pkey=key)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.get('haha.zip','haha2.zip')
上传/下载文件--秘钥

(4)参考

14、时间之time模块 和 datetime模块

14.1、time模块

(1)安装

  内置模块

  import time

(2)使用说明

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

  • 时间戳timestamp               1522924616.3162944,1970年1月1日之后的秒,即:time.time()
  • 格式化的字符串format time    2018-04-05 18:36:56,    即:time.strftime('%Y-%m-%d')
  • 结构化时间struct time          time.struct_time(tm_year=2018, tm_mon=4, tm_mday=5, tm_hour=18, tm_min=36, tm_sec=56, tm_wday=3, tm_yday=95, tm_isdst=0),元组包含了:年、日、星期等... time.struct_time    即:time.localtime()

  转换示意图

  

time()  # 返回当前时间的时间戳
localtime([secs])  # 将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
gmtime([secs])  # 和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
mktime(t)  # 将一个struct_time转化为时间戳。
asctime([t])  # 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。如果没有参数,将会将time.localtime()作为参数传入。
ctime([secs])  # 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
strftime(format[, t])  # 把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。如果元组中任何一个元素越界,ValueError的错误将会被抛出。
time.strptime(string[, format])  # 把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
sleep(secs)  # 线程推迟指定的时间运行,单位为秒。
clock()  # 这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间,即两次时间差。
参数说明
%y 两位数的年份表示(00-99%Y 四位数的年份表示(000-9999%m 月份(01-12%d 月内中的一天(0-31%H 24小时制小时数(0-23%I 12小时制小时数(01-12%M 分钟数(00=59%S 秒(00-59%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
格式化占位符说明

(3)验证

# 时间戳
time.time()  # 1522935462.4855645

# 格式化时间
time.asctime()  # 'Thu Apr  5 21:30:04 2018',参数是struct time,默认参数是time.localtime()
time.asctime(time.localtime())  # 'Thu Apr  5 21:35:27 2018',参数是struct time
time.asctime(time.localtime(150000))  # 'Sat Jan  3 01:40:00 1970',参数是struct time
time.ctime()  # 'Thu Apr  5 21:35:13 2018',参数是时间戳,默认参数是time.time()
time.ctime(time.time())  # 'Thu Apr  5 21:35:06 2018',参数是时间戳
time.ctime(150000)  # 'Thu Jan  1 08:25:00 1970',参数是时间戳

# struct time
time.localtime()  # 本地时间,timezone为+8,以后默认使用本地时间。默认参数是time.time()。  # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=5, tm_hour=18, tm_min=59, tm_sec=56, tm_wday=3, tm_yday=95, tm_isdst=0)
t = time.localtime()
# t.tm_year,t.tm_mon,t.mday。。。
time.localtime(12313123)  # 参数是时间戳 time.struct_time(tm_year=1970, tm_mon=5, tm_mday=23, tm_hour=20, tm_min=18, tm_sec=43, tm_wday=5, tm_yday=143, tm_isdst=0)
time.gmtime()  # 格林威治时间,timezone为0。默认参数是time.time()


# 格式转换
################## 时间戳 <--> 结构化时间 ########################################
# 时间戳 转换为 struct time
time.localtime(time.time())  # 时间戳转换为struct time,time.localtime(123123543)
# struct time 转换为 时间戳
time.mktime(time.localtime())  # struct time转换为时间戳,本地时间转为时间戳

################# 格式化时间 <--> 结构化时间 ######################################
time.strftime("%Y-%m-%d",time.localtime())  # '2018-04-05',struct time 转换为 结构化时间
# time.strftime('%y/%m/%d  %H:%M:%S')  # '18/04/05  19:05:18'
time.strptime('2008-03-12',"%Y-%m-%d")  # 将字符串时间转换成结构化时间
time.strptime('Thu Apr 05 21:52:01 2018')  # 默认格式"%a %b %d %H:%M:%S %Y",等于下面
time.strptime('Thu Apr 05 21:52:01 2018',"%a %b %d %H:%M:%S %Y")  # "%a %b %d %H:%M:%S %Y"


# 其他
time.sleep(2)
time模块 验证

(4)参考

14.2、datetime模块

(1)安装

  内置模块

  import datetime

(2)使用说明

 

  与time模块一样,时间分为时间戳timestamp、格式化字符串format time、结构化时间struct time,转换关系一直。  

  datetime说明

  有如下5个类

  • class datetime.date: 一个理想化的日期, 提供year, month, day属性
  • class datetime.time: 一个理想化的时间, 提供hour, minute, second, microsecond, tzinfo.
  • class datetime.datetime: 日期和时间的组合.提供year, month, day, hour, minute, second, microsecond, tzinfo.
  • class datetime.timedelta: 表达两个date,time和datetime持续时间内的微妙差异.
  • class datetime.tzinfo: 时间对象的抽象基类.
################ date类 #################

# 类属性
date.min: 返回 date(MINYEAR, 1, 1).
date.max: 返回 date(MAXYEAR, 12, 31).
date.year: 返回 年, MINYEAR和MAXYEAR之间
date.month: 返回 月, 1到12月之间
date.day: 返回 1到 n 之间.

# 类方法
date.replace(year, month, day):返回一个相同值的data对象, 除了这些参数给关键字指定新的值.
date.timetuple(): 返回一个time.struct_time对象.
date.toordinal(): 返回一个Gregoian Calendar对象.
date.weekday(): 返回day of the week. 星期一为0,星期日为6.
date.isoweekday(): 返回day of the week. 星期一为1,星期日为7.
date.isocalendar(): 返回一个三元组, (ISO year, ISO week number, ISO weekday).
date.isoformat(): 返回 一个'YYYY-MM-DD'的字符串格式.
date.ctime(): 返回一个字符串日期, d.ctime() 等同于 time.ctime(time.mktime(d.timetuple())).
date.strftime(format): 返回一个字符串日期, 格式自定义.

################ datetime类 #################

# 类属性
datetime.min: datetime(MINYEAR, 1, 1).
datetime.max: datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999).

# 实例属性
datetime.year: 1 至 9999
datetime.month: 1 至 12
datetime.day: 1 至 n
datetime.hour: In range(24). 0 至 23
datetime.minute: In range(60).
datetime.second: In range(60).
datetime.microsecond: In range(1000000).


# 类方法
datetime.today(): 返回当前本地datetime.随着 tzinfo None. 这个等同于datetime.fromtimestamp(time.time()).
datetime.now([tz]): 返回当前本地日期和时间, 如果可选参数tz为None或没有详细说明,这个方法会像today().
datetime.utcnow(): 返回当前的UTC日期和时间, 如果tzinfo None ,那么与now()类似.
datetime.fromtimestamp(timestamp[, tz]): 根据时间戳返回本地的日期和时间.tz指定时区.
datetime.utcfromtimestamp(timestamp): 根据时间戳返回 UTC datetime.
datetime.fromordinal(ordinal): 根据Gregorian ordinal 返回datetime.
datetime.combine(date, time): 根据date和time返回一个新的datetime.
datetime.strptime(date_string, format): 根据date_string和format返回一个datetime.

# 实例方法
datetime.date(): 返回相同年月日的date对象.
datetime.time(): 返回相同时分秒微秒的time对象.
datetime.replace(kw): kw in [year, month, day, hour, minute, second, microsecond, tzinfo], 与date类似.


################ time类 #################
# 与上差不多
说明

时区转换

from datetime import datetime, timedelta, timezone

utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
print(utc_dt)
cn_dt = utc_dt.astimezone(timezone(timedelta(hours=8)))
print(cn_dt)
jan_dt = utc_dt.astimezone(timezone(timedelta(hours=9)))
print(jan_dt)
cn_2_jan_dt = cn_dt.astimezone(timezone(timedelta(hours=9)))
print(cn_2_jan_dt)



# 实测
                if field.value > 958838733000:  # 2000-01-01
                    dt = datetime.fromtimestamp(field.value / 1000)
                    dt = dt.astimezone(timezone(timedelta(hours=8)))

 

(3)验证

# date类  date(year,month,day)
datetime.date.today()  # datetime.date(2018, 4, 5)  2018-04-05
# 初始化
td = datetime.date(2018,10,1)
# td.year  # 2018  int
# td.__getattribute__("year")
# td.month  # 10  int
# td.__getattribute__("month")
# td.day  # 1  int
# td.__getattribute__("day")

# 比较大小
a=datetime.date(2017,3,1)
b=datetime.date(2017,3,15)
a == b  # a.__eq__(b)  # False
a >= b  # a.__ge__(b)  # False
a > b   # a.__gt__(b)  # False
a <= b  # a.__le__(b)  # True
a < b   # a.__lt__(b)  # True
a != b  # a.__ne__(b)  # True

# 差值
a=datetime.date(2017,3,1)
b=datetime.date(2017,3,15)
a - b  # a.__sub__(b)  # datetime.timedelta(-14)
b - a  # a.__rsub__(b)  # datetime.timedelta(14)
# x = a - b
# x.days  # -14  int

# ISO标准化日期
a = datetime.date(2017,3,22)
a.isocalendar()  # (2017, 12, 3)  tuple  返回一个包含三个值的元组,三个值依次为:year年份,week number周数,weekday星期数(周一为1…周日为7)
a.isoformat()  # '2017-03-22'  str  返回符合ISO 8601标准 (YYYY-MM-DD) 的日期字符串;
a.isoweekday()  # 3  返回符合ISO标准的指定日期所在的星期数(周一为1…周日为7)
a.weekday()  # 2 与isoweekday(...)相似的还有一个weekday(...)方法,只不过是weekday(...)方法返回的周一为 0, 周日为 6


# 其他
a = datetime.date(2017,3,22)
a.timetuple()  # 该方法为了兼容time.localtime(...)返回一个类型为time.struct_time的数组,但有关时间的部分元素值为0
a.toordinal()  # 返回公元公历开始到现在的天数。公元1年1月1日为1
datetime.date.resolution  # date对象表示日期的最小单位。这里是天。
datetime.date.fromtimestamp(time.time())  # datetime.date(2018, 4, 5) 根据给定的时间戮,返回一个date对象
datetime.date.today()  # 返回当前日期
datetime.date.max  # date类能表示的最大的年、月、日的数值
datetime.date.min  # date类能表示的最小的年、月、日的数值

# 格式化
a = datetime.date(2017,3,22)
a.strftime("%Y%m%d")  # '20170322'  a.__format__("%Y%m%d")
# a.__format__('%Y-%m-%d')  # '2017-03-22'  <class 'str'>
# a.__format__('%Y/%m/%d')  # '2017/03/22'
# a.__format__('%y/%m/%d')  # '17/03/22'
# a.__format__('%D')  # '03/22/17'
a.__str__()  # '2017-03-22' str
a.ctime()  # 'Wed Mar 22 00:00:00 2017'
b = datetime.date.today()  # datetime.date(2018, 4, 5)
b.ctime()  # 'Thu Apr  5 00:00:00 2018'
date类
import datetime

# time类

a = datetime.time(12,20,59,899)  # datetime.time(12, 20, 59, 899)
a.hour  # 12  a.__getattribute__("hour")


# 比较大小
# 与date类一致


# 其他
datetime.time.max  # datetime.time(23, 59, 59, 999999)
datetime.time.min  # datetime.time(0, 0)
datetime.time.resolution  # datetime.timedelta(0, 0, 1)


# 格式化
# 与date类一致,__format__(),strfttime()


# ISO标准输出
a = datetime.time(12,20,59,899)
a.isoformat()  # '12:20:59.000899'
time类
import time
import datetime
# datetime类
# datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])

a = datetime.datetime.now()  # datetime.datetime(2018, 4, 5, 23, 9, 54, 826895)
a.date()  # 返回datetime对象的日期部分 datetime.date(2018, 4, 5)
a.time()  # 返回datetime对象的时间部分 datetime.time(16, 9, 33, 494248)
a.utctimetuple()  # 返回UTC时间元组 time.struct_time(tm_year=2018, tm_mon=4, tm_mday=5, tm_hour=23, tm_min=9, tm_sec=54, tm_wday=3, tm_yday=95, tm_isdst=0)

datetime.datetime.utcnow()  # datetime.datetime(2018, 4, 5, 15, 12, 17, 336671)

# 格式化时间 <--> datetime
datetime.datetime.strptime('2017-3-22 15:25','%Y-%m-%d %H:%M')  # datetime.datetime(2017, 3, 22, 15, 25)
datetime.datetime.strftime(datetime.datetime.now(),'%Y-%m-%d %X')  # '2018-04-05 23:18:01'
# datetime.datetime.strptime('2017-3-22 15:25','%Y-%m-%d %H:%M').timetuple()  # struct time

datetime.datetime.fromtimestamp(123123123)  # datetime.datetime(1973, 11, 26, 8, 52, 3)
datetime.datetime.utcfromtimestamp(time.time())  # datetime.datetime(2018, 4, 5, 15, 13, 38, 693083)
datetime类
a = datetime.datetime.now()  # datetime.datetime(2018, 4, 5, 23, 26, 18, 882579)
tr = datetime.timedelta(days=10,hours=3)
a - tr  # datetime.datetime(2018, 3, 26, 20, 26, 18, 882579)
timedelta类

 

1.获取当前日期时间
2.获取上个月第一天和最后一天的日期
3.获取时间差 时间差单位为秒
4.计算当前时间向后8个小时的时间
5.计算上周一和周日的日期
6.计算指定日期当月最后一天的日期和本月天数
7.计算指定日期下个月当天的日期
8.获得本周一至今天的时间段并获得上周对应同一时间段

# 1.获取当前日期时间
import datetime

now = datetime.datetime.now()  # datetime.datetime(2018, 4, 6, 0, 35, 22, 249989)
today = datetime.date.today()  # datetime.date(2018, 4, 6)
now.date()  # datetime.date(2018, 4, 6)
now.time()  # datetime.time(0, 35, 22, 249989)


# 2.获取上个月第一天和最后一天的日期
today = datetime.date.today()  # datetime.date(2018, 4, 6)
mlast_day = datetime.date(today.year, today.month, 1) - datetime.timedelta(1)  # datetime.date(2018, 3, 31)
mfirst_day = datetime.date(mlast_day.year, mlast_day.month, 1)  # datetime.date(2018, 3, 1)


# 3.获取时间差  时间差单位为秒
start_time = datetime.datetime.now()  # datetime.datetime(2018, 4, 6, 0, 38, 30, 119113)
end_time = datetime.datetime.now()  # datetime.datetime(2018, 4, 6, 0, 38, 34, 10000)
(end_time - start_time).seconds  # 3


# 4.计算当前时间向后8个小时的时间
d1 = datetime.datetime.now()  # datetime.datetime(2018, 4, 6, 0, 40, 9, 454170)
d2 = d1 + datetime.timedelta(hours=8)  # datetime.datetime(2018, 4, 6, 8, 40, 9, 454170)


# 5.计算上周一和周日的日期
today = datetime.date.today()  # datetime.date(2018, 4, 6)
today_weekday = today.isoweekday()  # 5
last_sunday = today - datetime.timedelta(days=today_weekday)  # datetime.date(2018, 4, 1)
last_monday = last_sunday - datetime.timedelta(days=6)  # datetime.date(2018, 3, 26)

# 6.计算指定日期当月最后一天的日期和本月天数
date = datetime.date(2017,12,20)
def eomonth(date_object):
    if date_object.month == 12:
        next_month_first_date = datetime.date(date_object.year + 1, 1, 1)
    else:
        next_month_first_date = datetime.date(date_object.year, date_object.month + 1, 1)
    return next_month_first_date - datetime.timedelta(1)

eomonth(date)  # datetime.date(2017, 12, 31)
eomonth(date).day  # 31


# 7.计算指定日期下个月当天的日期
date = datetime.date(2017,10,31)
# date = datetime.date(2017,12,20)

def eomonth(date_object):
    if date_object.month == 12:
        next_month_first_date = datetime.date(date_object.year + 1, 1, 1)
    else:
        next_month_first_date = datetime.date(date_object.year, date_object.month + 1, 1)
    return next_month_first_date - datetime.timedelta(1)

def edate(date_object):
    if date_object.month == 12:
        next_month_date = datetime.date(date_object.year+1, 1,date_object.day)
    else:
        next_month_first_day = datetime.date(date_object.year,date_object.month+1,1)
        if date_object.day > eomonth(next_month_first_day).day:
            next_month_date = datetime.date(date_object.year,date_object.month+1,eomonth(next_month_first_day).day)
        else:
            next_month_date = datetime.date(date_object.year, date_object.month+1, date_object.day)
    return next_month_date
edate(date)  # datetime.date(2018, 11, 30)
# edate(date)  # datetime.date(2018, 1, 20)


# 8.获得本周一至今天的时间段并获得上周对应同一时间段
today = datetime.datetime.now()  # datetime.datetime(2018, 4, 6, 1, 0, 44, 796079)
this_monday = today - datetime.timedelta(days=today.isoweekday()-1)  # datetime.datetime(2018, 4, 2, 1, 0, 44, 796079)
last_monday = this_monday - datetime.timedelta(days=7)  # datetime.datetime(2018, 3, 26, 1, 0, 44, 796079)
last_weekday = today - datetime.timedelta(days=7)  # datetime.datetime(2018, 3, 30, 1, 0, 44, 796079)
一些题目

(4)参考

https://blog.csdn.net/cmzsteven/article/details/64906245

15、collections模块

http://www.cnblogs.com/fat39/p/7266344.html

 

posted @ 2018-04-26 16:11  fat39  阅读(428)  评论(0编辑  收藏  举报