day17-常用模块之hashlib模块,subprocess模块,os模块和sys模块以及configparter模块
昨天我们讲了不少常用的模块,有 re 正则模块, json和pickle俩种数据交换格式模块,还有俩种时间模块,time和datetime已经一个伪随机数模块random.那么今天我们接着讲其他的常用内置模块.
一. hashlib模块
hashlib简介
1、什么叫hash:
- hash是一种算法(不同的hash算法只是复杂度不一样)(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值
2、hash值的特点是(hash值/产品有三大特性:):
-
1.只要传入的内容一样并且指定的算法也一样,得到的hash值必然一样 ==> 即 hash值 = 内容 + 算法
-
2.不能由hash值返解成内容 ====> 即一个内容一旦被hash成了一个hash值,就不可以返回成原内容了.
-
3.只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的(如从网上下载文件,下载完成之后要进行hash校验,保证网络传输没有丢包) ====> 即 相同hash值的长度是固定的
基于1和3可以做文件下载一致性的校验
基于1和2可以对用户密码进行加密
hash算法就像一座工厂,工厂接收你送来的原材料(可以用m.update()为工厂运送原材料),经过加工返回的产品就是hash值
现在知道了hash值大概是干什么的,接下来就学一下,这个模块的用法即可
hashlib用法
本用法案例以md5 演示,和其他的hash算法使用都一样
我们向导入我们的hashlib模块
import hashlib
然后我们来开始我们的案例介绍
hashlib这个模块下面有一堆的算法,下面为全部的算法列表
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
'blake2b', 'blake2s',
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
'shake_128', 'shake_256')
下面我们以md5来介绍(其他算法用法一样,长度不一)
hashlib.md5() 这时候会返回一个 hash 对象,
obj = hashlib.md5()
我们要想对数据进行hash处理,就先造一个hash对象,这个obj就是返回的对象
ps:注意,md5 后面一定要加括号,因为pycharm不会默认为我们加上,所以有时候可能会遗漏,而且括号内可以传参,参数表示要hash的数据,只能是二进制的,所以你传入的字符串必须得指定编码encode('utf-8')
obj = hashlib.md5("你好啊".encode('utf-8'))
然后我们可以调用其下的 update() 方法
这个就是为obj对象 添加你要hash的数据,也是只能hash二进制
obj.update("你好".encode('utf-8'))
obj.update("hello".encode('utf-8'))
obj.update("哈哈".encode('utf-8'))
该方法没有返回值,返回值为None
想要查看其hash之后的内容长撒样,可以使用obj下面的 hexdigest()
方法
# 内容为"你好啊你好hello哈哈"的二进制
print(m.hexdigest()) # 这是返回的hash值 43b2fa0da902a2d9175fb4d4b858e5d5
需要注意的是,它的内容可以分为多次 update
添加到 对象内,并且会将多次的update的内容进行拼接,只有调用hexdigest
方法才返回它的内容的返回值
即,下面多次update()和上面的几次返回的hash值是一样的
m1 = hashlib.md5("你好啊".encode('utf-8')
m1.update("你".encode('utf-8'))
m1.update("好".encode('utf-8'))
m1.update("hello".encode('utf-8'))
m1.update("哈".encode('utf-8'))
m1.update("哈".encode('utf-8'))
# "你好啊你好hello哈哈"
print(m1.hexdigest()) # 43b2fa0da902a2d9175fb4d4b858e5d5
我们到网站下下载完我们的文件时,其实它就是通过我们的hash进行判断,你下载完的文件是不是一个完整的文件,还是有破损的.所以我们的操作是下载完文件后,有一段时间的校验.下载完文件这是俩个步骤.
下面这个案例.可以模拟下载完文件,进行hash匹配
m = hashlib.md5()
with open(r'下载的文件路径', mode='rb') as f:
for line in f:
m.update(line)
res = m.hexdigest()
print(res)
我们用的方法是通过遍历整个文件,去进行一行一行的hash,但是当这个文件很大的时候,我们下载完一个文件,我们这个hash的话就会占用很长的时间,毕竟要将完整的文件hash.但是用户不知道啊,它只会感觉下载你这里的文件下载很慢,所以它可能下次就不来你这下载文件了.
所以这时候聪明的程序员们就想到了我们小时候学的抽样调查.我们可以不要hash所以的文件内容,可以取点,抽样取几个点,例如 10% 的时候去一次 ,往后取10个字符进行hash, 27%的时候又取一次值,也往后取10个字符进行hash...抽个6次 当这6次都和原文件的hash一样时,我们就可以确认这个文件没有丢失,是一个完整的.
当然了,也有可能存在偶然性,但是你要知道我们进行比对的俩个文件一般都是一样的,这时候再每次断点取值还都是一样的,那有破损的情况可能就为0了.
加密案例:用户注册,认证
import hashlib
USER_LIST = []
def get_md5(data):
obj = hashlib.md5("12:密码加盐".encode('utf-8'))
obj.update(data.encode('utf-8'))
result = obj.hexdigest()
return result
def register():
print('用户注册'.center(50, '-'))
while True:
user = input('请输入用户名n退出:').strip()
if user.lower() == 'n':
return
pwd = input('请输入密码:').strip()
temp = {'username': user, 'password': get_md5(pwd)}
USER_LIST.append(temp)
def login():
print('用户登陆'.center(50, '-'))
user = input('请输入用户名:').strip()
pwd = input('请输入密码:').strip()
for item in USER_LIST:
if item['username'] == user and item['password'] == get_md5(pwd):
return True
register()
result = login()
if result:
print('登陆成功')
else:
print('登陆失败')
最后将一个密码加盐,只要是加密,都是可以破解的.但是当破解的难度达到一定程度时,就会让一些人望而怯畏.那我们可以通过加盐的方式给 数据 进行 进一步的加大破解难度.即可在传输数据的时候,给他加一些其他的关键字的无用内容
m = hashlib.md5()
m.update("天王".encode('utf-8'))
m.update("123jkey".encode('utf-8')) # 这是我的密码
m.update("盖地虎".encode('utf-8'))
print(m.hexdigest())
上面案例就是 我的密码信息在中间,但是我给的内容是 "天王123jkey盖地虎" 这时候,破解的人就更难破解出对的密码了.
二. subprocess模块
python3. subporcess 子进程管理模块
subprocess模块允许你启动一个新的进程,连接输入/输出/错误的管道,
获得子进程的返回码。这个模块目标是代替一些老的模块,比如os.system和os.spawn.
下面我们来介绍subprocess模块的使用。
使用subprocess模块
在所有可以使用此模块的场景下首先推荐使用run()方法。更高级的用法可以直接使用Popen接口。
run()方法是在python 3.5版本中加入的。方法如下:
subprocess.run(args, *, stdin=None, input=None, stdout=None,
stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
args参数表示需要执行的命令,主进程会等待子进程执行完成,并返回一个CompletedProcess实例。
上面的一些参数只不过是一个常用的参数,下面会进行介绍。它的全部的参数是很多的,就像Popen的构造函数一样。除了timeout,input以及check参数外,其他的参数都会传递给Popen接口。也就是说Popen接口是核心。run方法只是外部的一个包装。
这个方法默认不捕获标准输出和标准错误。如果需要捕获的话,需要传递PIPE给stdout和stderr参数。
timeout参数传递给Popen.comunicate()方法。如果超时了,子进程会被杀死并且等待。TimeoutExpired会在子进程终止后被抛出。
input参数也传递给Popen.communicate()方法,从而传递给子进程的标准输入。如果要是用这个参数,必须传递一个字节序列,如果编码和错误指定了或者universal_newlines是true的话可以传递字符串。在使用的使用内部的Popen对象会自动创建,并且stdin=PIPE,stdin参数也就可能不会被用到。
check是true的情况,如果进程返回一个非零码,CalledProcessError异常会被抛出,此异常的属性包括参数,退出码和stdout,stderr。
如果编码和错误被指定,或者universal_newlines是true。stdin,stdout和stderr的文件对象就会默认使用编码和错误或者io.TextIOWrapper以文本模式打开。否则文件对象的打开方式为二进制模式。
Popen构造函数
但我们主要要将的还是 Popen构造函数
Popen是subprocess的核心,子进程的创建和管理都靠它处理。它提供了很多灵活的参数,可以让开发者实现一些不太常见的实例。构造函数如下:
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(),
*, encoding=None, errors=None)
12345
此类可以在一个新的进程中执行子程序。在POSIX系统中,这个类使用os.execvp()来执行子程序。在windows中使用Windows的CreateProcess()方法。参数解释如下:
args:表示要执行的命令,应当是一个参数的序列,或者就是一个字符串。一般推荐使用序列进行传递。但是如果shell指定为True的话,推荐使用字符串。
bufsize:缓冲区大小。当创建标准流的管道对象时使用。默认-1
0:不使用缓冲区
1:表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
正数:表示缓冲区大小
负数:表示使用系统默认的缓冲区大小。
executable:指定一个替代的程序去执行。这个参数几乎不会被用到。当shell=False的时候此参数替代args执行,然而,原始的args依旧传递给程序。很多程序把args当做命令的名字,而不是真正执行的程序。如果shell=True,在POSIX上此参数指定一个替代的shell来替换默认的/bin/sh。
stdin,stdout和stderr:分别表示标准输入,输出,和错误流。可用的参数是PIPE,DEVNULL,文件描述符,文件对象或者None。
preexec_fn:设置一个可访问的对象,在子进程执行之前会调用这个对象。
close_fds:如果是Ture,那么文件描述符除了0,1和2外,在子进程执行之前都会被关闭。在POSIX上总是为True.在windows上,标准流为None是为Ture,不能通知指定True和标准流。
cwd:在子进程执行之前改变工作目录,
restore_signals:存储进程信号,默认为True
start_new_session:如果是True,则在子进程执行之前条用系统setsid方法。
encoding,errors:如果指定了,那么标准流会以文本模式打开。
Popen对象方法
poll():检查进程是否终止,如果终止返回returncode,否则返回None。
wait(timeout):等待子进程终止。
communicate(input,timeout):和子进程交互,发送和读取数据。
send_signal(singnal):发送信号到子进程
terminate():停止子进程,也就是发送SIGTERM信号到子进程。
kill():杀死子进程。发送SIGKILL信号到子进程
实现cmd的例子(因为我这个是windows系统,所以是cmd)
def my_cmd(cmd):
obj = subprocess.Popen(cmd,
shell=True, # 表示以shell语句执行
stdout=subprocess.PIPE, # 表示将语句正确时,将执结果添加到管道
stderr=subprocess.PIPE, # 表示语句错误时,放入管道的内容
)
cmd_res = obj.stdout.read() # 表示拿到语句正确的返回值
cmd_error_res = obj.stderr.read() # 表示拿到语句错误的返回值
if cmd_res:
return cmd_res.decode('gbk')
return cmd_error_res.decode('gbk')
print(my_cmd('dir'))
print(my_cmd('tasklist'))
print(my_cmd('xac'))
需要注意的是俩个进程之间是相互隔离的,因此俩个进程需要数据共享就必须要通过管道实现.
三. os模块以及sys模块
Python3 OS 文件/目录方法
os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:
序号 | 方法及描述 |
---|---|
1 | os.access(path, mode)检验权限模式 |
2 | os.chdir(path) 改变当前工作目录 |
3 | os.chflags(path, flags)设置路径的标记为数字标记。 |
4 | os.chmod(path, mode)更改权限 |
5 | os.chown(path, uid, gid)更改文件所有者 |
6 | os.chroot(path)改变当前进程的根目录 |
7 | os.close(fd) 关闭文件描述符 fd |
8 | os.closerange(fd_low, fd_high) 关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 |
9 | os.dup(fd)复制文件描述符 fd |
10 | os.dup2(fd, fd2) 将一个文件描述符 fd 复制到另一个 fd2 |
11 | os.fchdir(fd) 通过文件描述符改变当前工作目录 |
12 | os.fchmod(fd, mode) 改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 |
13 | os.fchown(fd, uid, gid) 修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 |
14 | os.fdatasync(fd) 强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 |
15 | os.fdopen(fd[, mode[, bufsize]])通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 |
16 | os.fpathconf(fd, name)返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 |
17 | os.fstat(fd)返回文件描述符fd的状态,像stat()。 |
18 | os.fstatvfs(fd)返回包含文件描述符fd的文件的文件系统的信息,Python 3.3 相等于 statvfs()。 |
19 | os.fsync(fd) 强制将文件描述符为fd的文件写入硬盘。 |
20 | os.ftruncate(fd, length) 裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 |
21 | os.getcwd() 返回当前工作目录 |
22 | os.getcwdu()]返回一个当前工作目录的Unicode对象 |
23 | os.isatty(fd)] 如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 |
24 | os.lchflags(path, flags)设置路径的标记为数字标记,类似 chflags(),但是没有软链接 |
25 | os.lchmod(path, mode)修改连接文件权限 |
26 | os.lchown(path, uid, gid)]更改文件所有者,类似 chown,但是不追踪链接。 |
27 | os.link(src, dst) 创建硬链接,名为参数 dst,指向参数 src |
28 | os.listdir(path) 返回path指定的文件夹包含的文件或文件夹的名字的列表。 |
29 | os.lseek(fd, pos, how)设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 |
30 | os.lstat(path)像stat(),但是没有软链接 |
31 | os.major(device)从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 |
32 | os.makedev(major, minor) 以major和minor设备号组成一个原始设备号 |
33 | [os.makedirs(path, mode]) 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 |
34 | os.minor(device) 从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 |
35 | [os.mkdir(path, mode]) 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 |
36 | [os.mkfifo(path, mode]) 创建命名管道,mode 为数字,默认为 0666 (八进制) |
37 | [os.mknod(filename, mode=0600, device]) 创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。 |
38 | [os.open(file, flags, mode]) 打开一个文件,并且设置需要的打开选项,mode参数是可选的 |
39 | os.openpty() 打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 |
40 | os.pathconf(path, name) 返回相关文件的系统配置信息。 |
41 | os.pipe() 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 |
42 | [os.popen(command, mode[, bufsize]]) 从一个 command 打开一个管道 |
43 | os.read(fd, n) 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 |
44 | os.readlink(path) 返回软链接所指向的文件 |
45 | os.remove(path) 删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 |
46 | os.removedirs(path) 递归删除目录。 |
47 | os.rename(src, dst) 重命名文件或目录,从 src 到 dst |
48 | os.renames(old, new) 递归地对目录进行更名,也可以对文件进行更名。 |
49 | os.rmdir(path) 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 |
50 | os.stat(path) 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 |
51 | [os.stat_float_times(newvalue]) 决定stat_result是否以float对象显示时间戳 |
52 | os.statvfs(path) 获取指定路径的文件系统统计信息 |
53 | os.symlink(src, dst) 创建一个软链接 |
54 | os.tcgetpgrp(fd) 返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 |
55 | os.tcsetpgrp(fd, pg) 设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg |
56 | os.ttyname(fd) 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 |
57 | os.unlink(path) 删除文件路径 |
58 | os.utime(path, times) 返回指定的path文件的访问和修改的时间。 |
59 | [os.walk(top, topdown=True[, onerror=None[, followlinks=False]]]) 输出在文件夹中的文件名通过在树中游走,向上或者向下。 |
60 | os.write(fd, str) 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 |
61 | os.path 模块 获取文件的属性信息。 |
62 | os.pardir() 获取当前目录的父目录,以字符串形式显示目录名。 |
常用的
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 输出用于分割文件路径的字符串 win下为;,Linux下为:
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.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.path.getsize(path) 返回path的大小
sys模块
sys模块:
sys 模块提供了许多函数和变量来处理 Python 运行时环境的不同部分.
常见用法:
sys.argv:命令行参数List,第一个元素是程序本身路径
sys.modules.keys(): 返回所有已经导入的模块列表
sys.exc_info():获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) :退出程序,正常退出时exit(0)
sys.hexversion :获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version :获取Python解释程序的版本信息
sys.maxint : 最大的Int值
sys.maxunicode:最大的Unicode值
sys.modules :返回系统导入的模块字段,key是模块名,value是模块
sys.path :返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform :返回操作系统平台名称
sys.stdout : 标准输出
sys.stdin :标准输入
sys.stderr : 错误输出
sys.exc_clear() :用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix :返回平台独立的python文件安装的位置
sys.byteorder :本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
sys.copyright : 记录python版权相关的东西
sys.api_version :解释器的C的API版本
sys.displayhook(value) :如果value非空,这个函数会把他输出到sys.stdout,并且将他保存进__builtin__._.指在python的交互式解释器里,'_' 代表上次你输入得到的结果,hook是钩子的意思,将上次的结果钩过来
sys.getdefaultencoding() :返回当前你所用的默认的字符编码格式
sys.getfilesystemencoding() :返回将Unicode文件名转换成系统文件名的编码的名字
sys.setdefaultencoding(name):用来设置当前默认的字符编码,如果name和任何一个可用的编码都不匹配,抛出 LookupError,这个函数只会被site模块的sitecustomize使用,一旦别site模块使用了,他会从sys模块移除
sys.builtin_module_names :Python解释器导入的模块列表
sys.executable :Python解释程序路径
sys.getwindowsversion():获取Windows的版本
sys.stdin.readline() :从标准输入读一行,sys.stdout.write("a") 屏幕输出a
案例:在交互式模式下,copy文件
import sys
src_file = sys.argv[1]
dst_file = sys.argv[2]
with open(r'%s' %src_file,mode='rb') as f1,\
open(r'%s' %dst_file,mode='wb') as f2:
for line in f1:
f2.write(line)
在交互中运行
C:\Users\菩萨>python3 Z:\线下培训\04-第四周\04-day04\a.py Z:\线下培训\04-第四周\03-day03\01-re模块\01-re模块的使用.py Z:\线下培训\04-第四周\04-day04\b.py
案例copy时的打印进度条
import sys
import time
import os
src_file = sys.argv[1]
dst_file = sys.argv[2]
def progress(percent, width=50):
if percent >= 1:
percent = 1
show_str = ('[%%-%ds]' % width) % (int(width * percent) * '#')
print('\r%s %d%%' % (show_str, int(100 * percent)), file=sys.stdout, flush=True, end='')
with open(r'%s' % src_file, mode='rb') as f1, \
open(r'%s' % dst_file, mode='wb') as f2:
data_size = os.path.getsize(src_file)
recv_size = os.path.getsize(dst_file)
for line in f1:
while recv_size < data_size:
time.sleep(0.01) # 模拟数据的传输延迟
recv_size += len(line) # 每次收line个字节
percent = recv_size / data_size # 接收的比例
progress(percent, width=70) # 进度条的宽度70
f2.write(line)
案例示范:
python3 Z:\线下培训\04-第四周\04-day04\a.py Z:\线下培训\04-第四周\03-day03\01-re模块\01-re模块的使用.py Z:\线下培训\04-第四周\04-day04\b.py
[######################################### ] 58%
有个模块也可以打印进度条tqdm
from tqdm import tqdm # pip3 install tqdm
import string
import time
for char in tqdm(string.ascii_uppercase):
time.sleep(0.1)
for i in tqdm(range(50)):
time.sleep(0.05)
for i in tqdm(range(500)):
time.sleep(0.01)
四. configparser模块
import configparser
# 一个配置文件模块
# 实例化 configparser对象
config = configparser.ConfigParser()
# 为对象绑定文件04-config.ini内容
config.read('04-config.ini')
res = config.sections() # 返回文件中的标题
print(res) # ['mysqld', 'client']
res2 = config.options('mysqld') # 返回标题为mysqld 的变量列表,只有key
print(res2) # ['k1', 'k2', 'user', 'age', 'is_admin', 'salary', 'log_path']
res3 = config.items('mysqld') # 返回标题为mysqld 的变量列表,有key和value
print(res3) # [('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31'), ('log_path', 'D:\\a\\b\\c.log')]
res4 = config.get('mysqld', 'log_path') # 获取到某个指定的变量的值
print(res4) # D:\a\b\c.log
res5 = config.getint('mysqld', 'age') # 获取的值默认都是字符串
print(res5, type(res5)) # 18 <class 'int'>
res6 = config.getboolean('mysqld', 'is_admin') # 文件中的小写true一样可以取到
print(res6, type(res6)) # True <class 'bool'>
#删除整个标题section2
config.remove_section('section2')
#删除标题section1下的某个k1和k2
config.remove_option('section1','k1')
config.remove_option('section1','k2')
#判断是否存在某个标题
print(config.has_section('section1'))
#判断标题section1下是否有user
print(config.has_option('section1',''))
#添加一个标题
config.add_section('egon')
#在标题egon下添加name=egon,age=18的配置
config.set('egon','name','egon')
config.set('egon','age',18) #报错,必须是字符串
#最后将修改的内容写入文件,完成最终的修改
config.write(open('a.cfg','w'))
添加一个conf.ini文件
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
'Compression': 'yes',
'CompressionLevel': '9'}
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022' # mutates the parser
topsecret['ForwardX11'] = 'no' # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
config.write(configfile)