Python基础知识:模块
目录
JSON模块&pickle模块
requests模块
time模块
datetime模块
logging模块
os模块
sys模块
hashlib模块
re模块、正则表达式
configparser模块
XML模块
shutil模块
subprocess 模块
JSON模块&pickle模块
1、安装模块的两种方法:
第一种:pip install 模块名
第二种:源码安装:先到官网下载模块的源码(选择download the tarball)----》先解压(解压文件夹中有一个setup.py文件)----》cd 目录----》pip setup.py install
2、JSON(JavaScript Object Notation)格式最初是JavaScript开发的,但随后成为一种常见格式,被包括Python在内的众多语言使用。模块json能够将简单的Python数据结构存储到文件中,并在程序再次运行时加载该文件中的数据;不仅可以在Python程序之间分享数据,还可以与使用其他编程语言的人分享,而且所有的.json类型的文件内容都是字符串形式的。
json.load() 读取文件内容,并将字符串转为基本数据类型;
json.dump()把基本类型数据存储到文件中;适用于所有的语言,适合跨平台使用,只支持Python中的基本数据类型;函数接受两个实参:要存储的数据以及可用于存储数据的文件对象;
pickle模块:功能同上,但是只能针对Python使用,会以字节的形式将数据存储到文件,但是支持Python中所有的数据类型,包括复杂的类等等。
#json.dump()存储,json.load()读取
import json
filename = r'json_file\favor_number.json'
with open(filename, 'r') as f_obj:
favor_number = json.load(f_obj)
print('I know your favorite number is %d.'%int(favor_number))
love_number = input('enter your favorite number:')
with open(filename,'w') as f_obj:
json.dump(love_number,f_obj)
#json.loads()将字符串形式的字典或列表,转为字典或列表
import json
s = "[1,2,3]"
li = json.loads(s)
print(li,type(li))#[1, 2, 3] <class 'list'>
#json.dumps()将字典或列表转为字符串
s = {"k":"v"}
dic = json.dumps(s)
print(dic,type(dic))#{"k": "v"} <class 'str'>
#如果字符串内部是字典,字典内部一定要用双引号,外部用单引号
n = '{"k":"v"}'
print(json.loads(n))
requests模块
#访问URL获取北京天气
import requests
import json
response = requests.get("http://wthrcdn.etouch.cn/weather_mini?city=北京")
response.encoding = "utf-8"
r = json.loads(response.text)
print(r)
time模块
import time time.time()#返回系统当前时间戳,从1970年Unix(Linux的前身)正式商用开始算起(秒);
time.ctime()#返回系统当前时间,字符串格式#Tue Nov 27 09:07:55 2018
print(time.gmtime())#将时间戳转换为struct_time格式,按0时区算,跟本地时间差8小时
#time.struct_time(tm_year=2018, tm_mon=11, tm_mday=27, tm_hour=1,
# tm_min=12, tm_sec=46, tm_wday=1, tm_yday=331, tm_isdst=0)
print(time.localtime())#将时间戳转换为struct_time格式,返回本地时间
#与time.localtime()功能相反,将struct_time格式转为时间戳格式
print(time.mktime(time.localtime()))
time.sleep(0.1)#程序睡眠0.1秒
#将本地时间转换成特定格式
tm =time.strftime("%Y-%m-%d %H-%M-%S",time.localtime())
print(tm)
tm = time.strptime("2018-11-27 09:33","%Y-%m-%d %H:%M")
print(tm)#将特定时间格式转换为struct_time格式,如果没有写秒,默认从0开始
datetime模块
import datetime
#获取系统当前日期
print(datetime.date.today())#2018-11-27
#将时间戳转换为日期格式
print(datetime.date.fromtimestamp(time.time()))#2018-11-27
#返回系统当前准确时间
current_time = datetime.datetime.now()
print(current_time)#2018-11-27 09:48:21.483993
#将时间转换为struct_time格式
print(current_time.timetuple())
#时间运算
print(datetime.datetime.now() + datetime.timedelta(days=10))
#替换当前时间,可单独替换年月日
print(current_time.replace(2014,12,12))
#日期格式的时间可以比较大小
old_time = current_time.replace(2014)
print(type(old_time))#<class 'datetime.datetime'>
print(current_time>old_time)#True
logging模块
1、用于便捷记录日志且线程安全的模块
2、日志等级:
CRITICAL = 50 (危险的)
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
3、输出到屏幕
import logging
logging.warning("user [alex] attempted wrong password more than 3 times")
logging.critical("server is down")
4、写入文件
#把日志写到文件里,level值表示只写入这个等级或以上等级
import logging
logging.basicConfig(filename='text_file\example.log',level=logging.INFO)
logging.debug('This message should go to the log file')#等级不够,不写入
logging.info('So should this')
logging.warning('And this, too')
#日志格式加上时间
logging.basicConfig(filename='text_file\example.log',level=logging.INFO,
format='%(asctime)s%(message)s',
datefmt='%Y-%m-%d %I-%M-%S %p')
logging.warning(" It's time to go home.")
5、日志同时输出屏幕和将日志类型分别写入多个文件
注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。
import logging
#创建日志类型
logger = logging.getLogger("测试日志")
#创建全局日志等级,全局等级为最低限制,局部只能高不能低,以全局等级为准
logger.setLevel(logging.DEBUG)
#创建输出屏幕对象和等级
sh = logging.StreamHandler()
sh.setLevel(logging.INFO)
#创建写入文件对象和等级
fh = logging.FileHandler("text_file\warning.log",'a',encoding='utf-8')
fh.setLevel(logging.WARNING)
#创建输出格式
formater1 = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
formater2 = logging.Formatter('%(asctime)s-%(filename)s-%(levelname)s-%(message)s')
#给输出对象添加输出格式
sh.setFormatter(formater1)
fh.setFormatter(formater2)
#将输出对象添加到logger
logger.addHandler(sh)
logger.addHandler(fh)
#执行输出命令
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
6、日志记录格式:
os模块
1、获取当前文件的绝对路径
import os
print(os.path.abspath(__file__)) #C:\Users\Administrator\Desktop\Pycharm_Projects\basic_knowledge\模块.py
2、获取当前路径的上一级路径
import os
print(os.path.dirname(os.path.abspath(__file__))) #C:\Users\Administrator\Desktop\Pycharm_Projects\basic_knowledge
3、调用另一个文件夹下的模块
import sys
import os
s = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(s)
#package为Python Package类型的文件夹
#不能使用import.login调用
from package import login
login.log()
4、当一个py文件中末尾加入下面的代码时,只有执行当前文件的时候,当前文件的特殊变量__name__ == "__main__",也即是说直接运行当前文件,就会直接执行函数;如果是导入到另一个文件中,只调用文件不会执行,只有执行文件时才会执行;如果py文件中没有if语句,直接在文件末尾调用了函数,也就是可以直接运行该文件,如果此时该文件被另一个文件调用了,函数会直接运行,不需要使用文件名.函数名的格式来执行函数。
if __name__ == "__main__":
main()
5、调用一个函数中的全局变量
import test
print(test.NAME)
6、模块中的特殊变量
#__doc__返回文件开头的注释
#__cached__字节码存放的位置
#__file__当前py文件的路径
#__package__当前模块所在的包
7、创建文件夹、子文件夹以及文件夹中的文件;
import os
#生成多层递归目录
os.makedirs('user_db/6225021542120/record')
os.makedirs('user_db/6225021542120/basic_info')
#另一种方法
card_num = ""
#"user_db"为第一级文件夹名,依次二级,三级目录
os.makedirs(os.path.join("user_db",card_num,"record"))
#再次在card_num目录下新建文件夹
os.makedirs(os.path.join("user_db",card_num,"basic_info"))
8、模块中用于提供系统级别的操作
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命令,直接显示
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所指向的文件或者目录的最后修改时间
sys模块
1、sys模块中的基本操作
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 #错误相关
2、view_bar(num,total)制作一个进度条
import sys
import time
def view_bar(num,total):
rate = num / total #求出每次给的num占总数的比例
rate_num = int(rate * 100) #转换成百分比形式,取整
r = "\r%s%d%%" % (">" * rate_num, rate_num) #\r表示重新回到当前行的初始位置
sys.stdout.write(r) #重新输出r
if __name__ == "__main__":
for i in range(0,101):
time.sleep(0.001)
view_bar(i,100) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>100%
hashlib模块
1、对密码123进行双层加密
import hashlib obj = hashlib.md5(bytes("asfdfdfdf",encoding="utf-8"))
obj.update(bytes('',encoding='utf-8'))
ret = obj.hexdigest()
print(ret)
re模块、正则表达式
1、python中re模块提供了正则表达式相关操作
字符:
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
次数:
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
正则分组:从已经匹配到的数据中再提取数据
import re
#精准匹配
print(re.findall('alex','alexfkalexslalwxlp'))#['alex', 'alex']
#'.'能匹配到换行符以外的所有字符
print(re.findall('al.x','alexfkalexshalwxkp'))#['alex', 'alex', 'alwx']
#'^'从字符串初始位置匹配
print(re.findall('^alex','alexfkalexslalwxlp'))#['alex']
#'$'从字符串末尾位置匹配,只有在末尾才能匹配到
print(re.findall('^alex','alexfkalexslalwalex'))#['alex']
#'*'表示x前面的字符匹配0到多次
print(re.findall('al.*x','alexfkalexshalwxkp'))#['alexfkalexshalwx']
print(re.findall('ale*x','alexfkalexshalwxkp'))#['alex', 'alex']
print(re.findall('al*x','fkalxshalwx'))#['alx']
#'+'表示x前面的字符匹配1到多次
print(re.findall('al.+x','fkalxshuulw'))#[]
#'?'表示x前面的字符匹配0或1次
print(re.findall('al.?x','fkalxshuulw'))#['alx']
#{}表示匹配的范围
print(re.findall('al.{0,5}x','fkalrrrrxshuulw'))#['alrrrrx']
#[]表示字母的范围,以上元字符在中括号内不再有原有的意义
print(re.findall('al[a-z]x','alqx'))#['alqx']
#"^"在中括号内表示否的意思,只要不是z,都可以匹配到
print(re.findall('al[^z]x','alqx'))#['alqx']
#[/d]表示数字
print(re.findall('al[\d]x','al3x'))#['al3x']
#\b匹配一个单词边界,也就是指单词和空格间的位置,空白和非字母数字都可以匹配到
print(re.findall(r'I\b','I%am a cat.'))#['I']
#split()以什么为界分割字符串
print(re.split('\d+','ane1two2three3four4'))
#['ane', 'two', 'three', 'four', '']
2、match(pattern, string, flags=0) 从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
# pattern: 正则模型
# string : 要匹配的字符串
# falgs : 匹配模式
#匹配模式:
#re.I--使匹配对大小写不敏感
#re.L--做本地化识别匹配
#re.M--多行匹配,影响^和$
#re.S--是.匹配包括换行符在内的所有字符
# 无分组
origin = "hello alex bcd abcd lge acd 19"
r = re.match("h\w+", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组结果 # 有分组 # 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来) r = re.match("h(\w+).*(?P<name>\d)$", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组
3、findall(pattern, string, flags=0) 获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖;空的匹配也会包含在结果中。
# 无分组
r = re.findall("a\w+",origin)
print(r) # 有分组
origin = "hello alex bcd abcd lge acd 19"
r = re.findall("a((\w*)c)(d)", origin)
print(r)
#[('bc', 'b', 'd'), ('c', '', 'd')]
#如果需要调用很多次,使用下面的方法更快速
s = "hello alex bcd alex lge alex acd 19"
obj = re.compile(r'a\w+')
print(obj.findall(s))
#['alex', 'alex', 'alex', 'acd']
4、search(pattern, string, flags=0) 浏览整个字符串去匹配第一个,未匹配成功返回None
# 无分组
origin = "hello alex bcd abcd lge acd 19"
r = re.search("a\w+", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组结果 # 有分组 r = re.search("a(\w+).*(?P<name>\d)$", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组
#正则表达式两个\匹配到一个\
import re
r = re.search(r"\\", 'ori\gin')
print(r.group())
5、sub( ) 替换匹配成功的指定位置字符串
sub(pattern, repl, string, count=0, flags=0)
# pattern: 正则模型
# repl : 要替换的字符串或可执行对象
# string : 要匹配的字符串
# count : 指定匹配个数
# flags : 匹配模式
# 与分组无关 origin = "hello alex bcd alex lge alex acd 19"
r = re.sub("a\w+", "", origin, 2)
print(r)
6、subn( ) 替换匹配成功的指定位置字符串,并返回替换次数
# 与分组无关 import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.subn(r"a\w+", "", origin)
print(r)
#('hello 999 bcd 999 lge 999 999 19', 4)
7、split( ) 根据正则匹配分割字符串
split(pattern, string, maxsplit=0, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# maxsplit:指定分割个数
# flags : 匹配模式
# 无分组
origin = "hello alex bcd alex lge alex acd 19"
r = re.split("alex", origin, 1)
print(r)
#['hello ', ' bcd alex lge alex acd 19'] # 有分组 origin = "hello alex bcd alex lge alex acd 19"
r1 = re.split("(alex)", origin, 1)
print(r1)
#['hello ', 'alex', ' bcd alex lge alex acd 19']
r2 = re.split("(al(ex))", origin, 1)
print(r2)
#['hello ', 'alex', 'ex', ' bcd alex lge alex acd 19']
print(re.split('\d+','ane1two2three3four4'))
#['ane', 'two', 'three', 'four', '']
8、常用正则表达式
IP:
^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$
手机号:
^1[3|4|5|8][0-9]\d{8}$
邮箱:
[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+
必须是字母和数字组合:
(?!^[a-zA-Z]+$)(?!^\d+$)[0-9a-zA-Z]{3,}
字母、数字、下划线:
(?!^[a-zA-Z]+$)(?!^\d+$)(?!^_+$)[0-9a-zA-Z_]{3,}
9、练习题:正则表达式实现计算器的+ - * /运算
需求分析:
表达式 = 8*5-2+(10-(8*5+6)/10+5)*(3-2)+8*(9-4)
1、从前到后找,找到第一个以(开始)结尾,中间不含有括号的表达式
2、正则表达式:\([^()]\)
定义两个函数:
1、def 处理加减乘除(表达式):
return 结果
2、def 处理括号(表达式):
while True:
#先找到第一个,分割成三部分,得到括号内的表达式,不要括号
re.split('\( [^()] \)',表达式,1)
#8*5-2+(10- 8*5+6 /10+5)*(3-2)+8*(9-4)
ret = 加减乘除(8*5+6)
#再把表达式连起来
8*5-2+(10- ret /10+5)*(3-2)+8*(9-4)
#再返回给函数,知道没有括号,直接给运算函数,得到最终结果
import re
import sys
def no_bracket_rules(expression):
'''计算没有括号的乘除运算'''
md_check = re.search(r'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',expression)
if md_check:#乘除存在
#得到第一个*或/运算表达式
data = md_check.group()
if len(data.split("*")) > 1:# 当可以用乘号分割,证明有乘法运算
part1, part2 = data.split("*") # 用乘号分割
result = float(part1)*float(part2)
else:
part1, part2 = data.split("/")# 用除号分割
if part2 == 0:
sys.exit("计算过程中有被除数为0的存在,计算表达式失败!")
else:
result = float(part1) / float(part2)
# 获取第一个匹配到的乘除计算结果value,将value放回原表达式
# 以第一个*或/组成的表达式为界分割表达式
s1, s2 = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', expression, 1)
# 将计算结果和剩下的表达式组合成新的字符串
new_exp = "%s%s%s" % (s1, result, s2)
return no_bracket_rules(new_exp)#递归表达式
else:#乘除不存在,在判断加减是否存在
expression = expression.replace('+-', '-') # 替换表达式里的所有'+-'
expression = expression.replace('--', '+') # 替换表达式里的所有'--'
expression = expression.replace('-+', '-') # 替换表达式里的所有'-+'
expression = expression.replace('++', '+') # 替换表达式里的所有'++'
as_check = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression)#匹配加减号
if not as_check: # 如果不存在加减号,则证明表达式已计算完成,返回最终结果
return expression
else:
#得到第一个+或-运算表达式
data = re.search('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression).group()
if len(data.split("+")) > 1: #以加号分割成功,有加法计算
part1, part2 = data.split('+')
value = float(part1) + float(part2) # 计算加法
elif data.startswith('-'): # 如果是以'-'开头则需要单独计算,因为是负数
#分割为三部分,分别为'',正数,正数
part1, part2, part3 = data.split('-')
value = -float(part2) - float(part3) # 计算以负数开头的减法
else: #正数的减法运算
part1, part2 = data.split('-')
value = float(part1) - float(part2) # 计算减法
# 以第一个+或-分割表达式
s1, s2 = re.split('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression, 1)
# 将计算后的结果替换回表达式,生成下一个表达式
new_exp = "%s%s%s" % (s1, value, s2)
return no_bracket_rules(new_exp) # 递归运算表达式 def bracket_rules(expression):
'''找到括号内的表达式,返回给计算函数'''
while True:
#验证表达式内是否含有以括号开始和结尾,且中间不含括号的
if re.findall(r"\(([^()]+)\)",expression):
# 找到第一个以(开始,以)结尾,且中间不含()的表达式
s_split = re.split(r"\(([^()]+)\)",expression,1)
ret = no_bracket_rules(s_split[1])#分割为三部分,中间为得到的表达式
# 将先前得到的表达式的计算结果和剩下的表达式组合成新的字符串
new_exp = "%s%s%s" % (s_split[0], ret, s_split[2])
return bracket_rules(new_exp)#返回函数,继续查找表达式
else:
#如果表达式内没有括号,就直接调用加减乘除函数进行计算
result = no_bracket_rules(expression)
return result s = "8*5-2+(10-(8*5+6)/10+5)+6*(3-2)+8*9-4"
ret = bracket_rules(s)
print(ret)#122.4
configparser模块
configparser用于处理配置文件,其本质上是利用open来操作文件。每个节点相当于一个key,下面的键值对相当于value;
首先创建config对象,然后读取文件config.read(文件),写入文件config.write(文件)
[section1] # 节点
k1 = v1 # 值
k2:v2 # 值 [section2] # 节点
k1 = v1 # 值
1、获取所有节点
import configparser config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.sections()
print(ret)
2、获取指定节点下所有的键值对
import configparser config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.items('section1')
print(ret)
3、获取指定节点下所有的建
import configparser config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.options('section1')
print(ret)
4、获取指定节点下指定key的值
import configparser config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8') #get函数可以将得到的字符串转换为相应类型数据,前提是可以转
v = config.get('section1', 'k1')
# v = config.getint('section1', 'k1')#转换为整数
# v = config.getfloat('section1', 'k1')#转换为浮点型
# v = config.getboolean('section1', 'k1')#转换为布尔值 print(v)
5、检查、删除、添加节点
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'))
6、检查、删除、设置指定组内的键值对
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', "")
config.write(open('xxxooo', 'w'))
XML模块
1、浏览器返回的数据类型:
a.HTML
b.Json
c.XML(XML是实现不同语言或程序之间进行数据交换的协议)
- 页面上做展示(字符串类型,一个XML格式数据)
- 配置文件(文件类型,内部数据XML格式)
2、操作XML:XML格式类型是节点嵌套节点,对于每一个节点均有以下功能,以便对当前节点进行操作:
from xml.etree import ElementTree as ET
# 直接解析XML文件
tree = ET.parse('xml_file\country.xml')
# 获取xml文件的根节点
root = tree.getroot()
#每一个节点都是一个Element对象
print(root)#<Element 'data' at 0x0000001E46461138>
print(root.tag)#获取当前节点的名字
print(root.attrib)#获取当前节点的属性{'title': 'total', 'age': '12'}
#遍历所有子节点,text获取节点中间的内容
for child in root:
print(child.tag,'-',child.attrib)
for grandchild in child:
print(grandchild.tag, grandchild.text)
# makeelement(tag,attrib)添加节点
# append(subelement)添加一个节点
# extend(elements)为当前节点扩展n个节点
# insert(index,subelement)为当前节点创建子节点,然后插入指定位置
# find(path)获取第一个寻找到的子节点
# findtext()获取第一个寻找到的子节点的内容
# findall(path)获取所有的子节点
# iterfind(path)获取所有子节点,并创建一个迭代器
# clear()清空所有节点
# get(key)获取当前节点的属性值
# print(root.attrib.get('title'))#total
# keys()获取当前节点的所有属性的key
# print(root.attrib.keys())#dict_keys(['title', 'age'])
# items()获取当前节点的所有属性值,每个属性都是一个键值对
# print(root.attrib.items())# dict_items([('title', 'total'), ('age', '12')])
# iter()在当前节点的子节点中根据节点名称寻找所有指定节点,并返回一个迭代器
# itertext()在当前节点的子孙中根据节点名称寻找所有指定的节点的内容,并返回一个迭代器
3、由于修改节点时,均是在内存中进行,其不会影响文件中的内容,所以,如果想要保存文件,则需要重新将内存中的内容写到文件。
############ 解析方式一 ############
from xml.etree import ElementTree as ET
# 利用ElementTree.parse将文件直接解析成XML对象
tree = ET.parse('xml_file\country.xml')#ElementTree类型
# 获取xml文件的根节点
root1 = tree.getroot()#element类型
#循环所有year节点,修改节点内容
for node in root1.iter('year'):
new_year = int(node.text) + 1
node.text = str(new_year)
#设置属性set(key,value)
node.set("name","charlie")
node.set("age","")
#删除属性 del
del node.attrib["name"]
#写入文件
tree.write(r'xml_file\country2.xml',encoding='utf-8') ############ 解析方式二 ############
# 利用ElementTree.XML将字符串解析成XML对象
str_xml = open('xml_file\country.xml', 'r').read()
# 将字符串解析成xml特殊对象,root代指xml文件的根节点
root2 = ET.XML(str_xml)#element类型
#循环所有year节点,修改节点内容
for node in root2.iter('year'):
new_year = int(node.text) + 1
node.text = str(new_year)
#设置属性set(key,value)
node.set("name","charlie")
node.set("age","")
#删除属性 del
del node.attrib["name"]
#写入文件,只有ElementTree类型的对象有写入功能
tree = ET.ElementTree(root2)
tree.write(r'xml_file\country3.xml',encoding='utf-8')
4、创建一个XML文件:<neighbor direction="W" name="Costa Rica" />如果节点没有内容,会进行自闭和
############ 创建方式一 ############
# #创建根节点
root_family = ET.Element('family')
#创建大儿子
son1 = ET.Element('son',{'name':'大儿子'})
#创建小儿子
son2 = ET.Element('son',{'name':'小儿子'})
#在大儿子中创建两个孙子
grandson1 = ET.Element('grandson',{'name':'大孙子'})
grandson2 = ET.Element('grandson',{'name':'二孙子'})
son1.append(grandson1)
son1.append(grandson2)
#把儿子添加到根目录
root_family.append(son1)
root_family.append(son2)
#写入文件
family_tree = ET.ElementTree(root_family)
family_tree.write(r'xml_file\family.xml',encoding='utf-8',
xml_declaration=True,short_empty_elements=False) ############ 创建方式二 ############
# 创建大儿子
son1 = root.makeelement('son', {'name': '儿1'})
grandson1 = son1.makeelement('grandson',{'name':'大孙子'}) ########### 创建方式三 ############
#创建节点大儿子
son1 = ET.SubElement(root, "son", attrib={'name': '儿1'})
grandson1 = ET.SubElement(son1,'grandson',attrib={'name':'大孙子'})
5、由于原生保存的XML时默认无缩进,如果想要设置缩进的话,需要修改保存方式,所以先定义一个保存方式:
from xml.dom import minidom
def prettify(elem):
"""将节点转换成字符串,并添加缩进。
"""
rough_string = ET.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent="\t")
root_family = ET.Element('family')
son1 = ET.Element('son',{'name':'大儿子'})
son2 = ET.Element('son',{'name':'小儿子'})
grandson1 = ET.Element('grandson',{'name':'大孙子'})
grandson2 = ET.Element('grandson',{'name':'二孙子'})
son1.append(grandson1)
son1.append(grandson2)
root_family.append(son1)
root_family.append(son2)
#调用方法写入文件
raw_str = prettify(root_family)
f = open(r"xml_file\family.xml",'w',encoding='utf-8')
f.write(raw_str)
f.close()
shutil模块
1、文件、文件夹基本操作
import shutil #将文件内容拷贝到另一个文件中
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
#拷贝文件
shutil.copyfile('f1.log', 'f2.log')
#仅拷贝权限,内容、组、用户均不变
shutil.copymode('f1.log', 'f2.log')
#仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log')
#拷贝文件和权限
shutil.copy('f1.log', 'f2.log')
#拷贝文件和状态信息
shutil.copy2('f1.log', 'f2.log')
#递归的去拷贝文件夹
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
#递归的去删除文件
shutil.rmtree('folder1')
#递归的去移动文件,它类似mv命令,其实就是重命名。
shutil.move('folder1', 'folder3')
2、压缩文件操作
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对象
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录
import shutil
ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
import shutil
ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
3、shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
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.namelist()#查看所有文件
z.extract(member)#解压单个文件
z.extractall()#解压所有文件
z.close()
import tarfile # 压缩
tar = tarfile.open('xml_file\your.tar','w')
#可以通过arcname来修改文件在压缩包中的名字
tar.add(r'xml_file\family.xml', arcname='son.xml')
tar.add(r'xml_file\country.xml', arcname='city.xml')
tar.close() # 解压
tar = tarfile.open('your.tar','r')
tar.getmembers()#获取压缩包所有成员,得到一个特殊对象
#解压单个成员,需要传递一个对象
obj = tar.getmember('text.py')
tar.extract(obj)
tar.extractall() # 可设置解压地址
tar.close()
subprocess 模块
1、call 、check_call、check_output
import subprocess #call执行命令,返回状态码
ret = subprocess.call(["ls", "-l"], shell=False)
ret = subprocess.call("ls -l", shell=True) #check_call执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
subprocess.check_call(["ls", "-l"])
subprocess.check_call("exit 1", shell=True) #check_output执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
subprocess.check_output(["echo", "Hello World!"])
subprocess.check_output("exit 1", shell=True)
2、subprocess.Popen(...)用于执行复杂的系统命令
参数:
- 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:用于设置子进程的当前目录
- env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
- universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
- startupinfo与createionflags只在windows下有效
- 将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
#执行普通命令
import subprocess
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True)
终端输入的命令分为两种:
- 输入即可得到输出,如:ifconfig
- 输入进行某环境,依赖再输入,如:python
import subprocess obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
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)
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)
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)
Python基础知识:模块的更多相关文章
- 1.7 Python基础知识 - 模块初识
在Python中有很多模块,模块对应的就是python源代码文件.模块中有Python程序自己附带的标准模块,还有很多其他人共享的第三方模块.模块中可以定义变量.函数和类.而多个功能类似的模块可以组织 ...
- python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。
本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...
- python 基础知识(一)
python 基础知识(一) 一.python发展介绍 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本 ...
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- python基础知识小结-运维笔记
接触python已有一段时间了,下面针对python基础知识的使用做一完整梳理:1)避免‘\n’等特殊字符的两种方式: a)利用转义字符‘\’ b)利用原始字符‘r’ print r'c:\now' ...
- Python 基础知识(一)
1.Python简介 1.1.Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时 ...
- python基础知识的学习和理解
参考链接:https://github.com/yanhualei/about_python/tree/master/python_learning/python_base python基础知识笔 ...
- Python基础知识(六)------小数据池,集合,深浅拷贝
Python基础知识(六)------小数据池,集合,深浅拷贝 一丶小数据池 什么是小数据池: 小数据池就是python中一种提高效率的方式,固定数据类型使用同一个内存地址 代码块 : 一个文 ...
- Python基础知识(五)------字典
Python基础知识(四)------字典 字典 一丶什么是字典 dict关键字 , 以 {} 表示, 以key:value形式保存数据 ,每个逗号分隔 键: 必须是可哈希,(不可变的数据类型 ...
- Python基础知识总结笔记(四)函数
Python基础知识总结笔记(四)函数python中的函数函数中的参数变量作用域偏函数PFA递归函数高阶函数BIFs中的高阶函数匿名函数lambda闭包Closure装饰器Decorator函数式编程 ...
随机推荐
- MySQL百万级、千万级数据多表关联SQL语句调优
本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化,使百万级.千万级数据表关联查询第一页结果能在2秒内完成(真实业务告警系统优化结果).希望读者能够理解S ...
- interface21 - web - Log4jConfigListener(Log4j加载流程)
前言 最近打算花点时间好好看看spring的源码,然而现在Spring的源码经过迭代的版本太多了,比较庞大,看起来比较累,所以准备从最初的版本(interface21)开始入手,仅用于学习,理解其设计 ...
- ContentProvider使用总结
近日来学习ContentProvider相关的知识,做了一个demo,想和网友分享下. 首先说一点相关的知识: 一:作用 ContentProvider是不同应用程序共享数据的接口,跟共享数据的别的方 ...
- winhex十六进制常用快捷键
Winhex的常用快捷键 摘要: Winhex 是一个专门用来对付各种日常紧急情况的工具.它可以用来检查和修复各种文件.恢复删除文件.硬盘损坏造成的数据丢失等.同时它还可以让你看到其他程序隐藏起来的文 ...
- Linux下网络文件系统NFS服务搭建易错点总结
一.环境准备: 1 [root@czh ~]# cat /etc/redhat-release 2 CentOS release 6.7 (Final) 3 [root@czh ~]# uname - ...
- Vue.js的复用组件开发流程
本文由蔡述雄发表 接下来我们会详细分析下如何完成由多个组件组成一个复用组件的开发流程. 下面先看看我们的需求 列表组件quiList.vue 本节我们主要要完成这样一个列表功能,每一行的列表是一个组件 ...
- mysql存储引擎选择(转)
MySQL 的存储引擎可能是所有关系型数据库产品中最具有特色的了,不仅可以同时使用多种存储引擎,而且每种存储引擎和MySQL之间使用插件方式这种非常松的耦合关系.由于各存储引擎功能特性差异较大,这篇文 ...
- JavaWeb学习 (十四)————JSP基础语法
一.JSP模版元素 JSP页面中的HTML内容称之为JSP模版元素. JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观. 二.JSP表达式 JSP脚本表达式(expression)用于将 ...
- 深入浅出 JVM GC(1)
# 前言 初级 Java 程序员步入中级程序员的有一个无法绕过的阶段------GC(Garbage Collection).作为 Java 程序员,说实话,很幸福,不用像 C 程序员那样,时刻关心着 ...
- Oracle字符串函数
Oracle字符串函数 平常我们用Oracle主要有两种字符串类型1.char始终为固定的长度,如果设置了长度小于char列的值,则Oracle会自动用空格填充的.当比较char时,Oracle用空格 ...