#os模块
import os,sys print(os.path.abspath(__file__)) #获取一个文件的绝对路径(此处括号内为__file__,代表获取此执行文件的绝度路径)
print(os.getcwd()) #获取当前工作路径
os.chdir('package0') #改变当前工作路径
os.chdir('..') #改变工作路径到上一层
os.makedirs('dir1/dir2/dir3') #递归生成文件夹
os.removedirs('dir1/dir2/dir3') #删除文件并返回上一层,若上一层目录为空,则也删除并再返回上一层
os.rmdir('dir11') #删除单个文件夹(目录),为空则无法删除
os.remove('111.py') #删除单个文件
print(os.listdir('module_test')) #以列表形式列出当前目录下所有文件名,不填值默认为当前工作路径
print(os.stat('test')) #查看指定文件具体信息
print(os.sep) #获取当前操作系统的分隔符,win下为\\,linux下为/
a=os.linesep #获取当前操作系统的换行符,win下\r\n,linux下\n
print(os.pathsep) #获取当前操作系统的路径分隔符(如环境变量路径的分隔),win下为 ; ,linux下 :
os.system('dir') #运行shell命令
print(os.path.split(__file__)) #将path分隔成目录和文件名,以二元组返回
print(os.path.dirname(__file__)) #返回path的目录,即os.path.split()的第一项
print(os.path.basename(__file__)) #返回path最后的文件名,如果最后以\或/结尾就会返回空值
print(os.path.exists('test')) #判断path是否存在,返回一个bool值
print(os.path.isabs('test')) #判断path是否是绝对路径
print(os.path.isdir('package0')) #判断path是否是目录
a = 'C:\\Users\\Administrator\\.PyCharm2018.3' #以系统分隔符拼接路径
b = 'config\\scratches\\text.py' c = os.path.join(a,b) print(c)
#sys模块
import sys print(sys.path) #获取系统环境变量
print(sys.platform) #获取系统平台名称
print(sys.version) #获取python解释器版本
sys.exit(0) #退出程序,正常退出为exit(0)
#sys.argv() 获取程序输入变量
#模拟一个进度条
import sys,time for i in range(30): sys.stdout.write('#') #向终端屏幕输出'#',print函数就是由这个写的
time.sleep(0.1) sys.stdout.flush() #刷新缓存,加载到屏幕上
#json模块 (用作任何语言之间的数据交换) #重要
#相当于eval的升级版
#用json模块,字符串统一用双引号 " "
#json转换后的类型其他语言都能用
#json.dumps工作流程:将所有'' 变为"",再转换为字符串
#json.loads 还原数据类型
import json dic={"name":"alex"} dic_str = json.dumps(dic) #这里其实已经是json字符串(其他语言都能用)
with open('json','w') as f1: f1.write(dic_str) with open('json','r') as f2: dic1=json.loads(f2.read()) #还原数据类型 print(type(dic1)) print(dic1)
#json.dump
import json dic={"name":"alex"} with open('json','w') as f: json.dump(dic,f) #以上相当于
import json dic={"name":"alex"} with open('json','w') as f: f.write(json.dumps(dic))
#json.load 和上同理
import json dic={"name":"alex"} with open('json','r') as f: print(json.load(f)) #等同于
import json dic={"name":"alex"} with open('json','r') as f: print(json.loads(f.read()))
#pickle模块
(可以用来把实例化的对象存入文本中,以后也能调用,具体看面向对象的大作业那节)
#使用方法完全与json模块一样,功能也一样,但只能用于python,不能用于其他语言
#不同在于json把对象处理成字符串,pickle处理成字节,故文件打开是需要用到b模式('rb','wb'...)
import pickle dic={"name":"alex"} print(type(pickle.dumps(dic))) #<class 'bytes'>
#序列化(将对象的信息转换为可以存储或传输的形式bytes):pickle.dumps()
import pickle dic={"name":"alex"} with open('pickle','wb') as f: f.write(pickle.dumps(dic))
#反序列化:pickle.loads()
#shelve模块
import shelve f=shelve.open('shelve') #打开一个名字为shelve的特殊文件用于存放字典(文件内容无需看),f为文件句柄
f['shelve']={'123'} #往里面存入字典
f['info']={'name':'alex','age':'18'} print(f.get('shelve')) #用f.get取出字典里的内容
print(f.get('info')['name']) f.close()
#xml模块 (xml文件,存放标签语言)
#比json模块出现的早,也是用于数据交换
#读取xml文档
import xml.etree.ElementTree as ET #将次模块记为 ET ,方便下面调用 (import xxx as xxx)
tree = ET.parse("xml_lesson.xml") root = tree.getroot() #获取根节点(根对象)
#tag方法(获取对象名(标签))
import xml.etree.ElementTree as ET #将次模块记为 ET ,方便下面调用 (import xxx as xxx)
tree = ET.parse("xml_lesson.xml") root = tree.getroot() #获取根节点(根对象)
print(root.tag) #获取根对象的标签
for i in root: #遍历根对象,得到子节点(对象)
print(i) print(i.tag) #获取子节点的标签
for j in i : print(j.tag) #获取子节点内容的标签
#attrib方法(获取标签对象属性,形式为键值对)
import xml.etree.ElementTree as ET #将次模块记为 ET ,方便下面调用 (import xxx as xxx)
tree = ET.parse("xml_lesson.xml") root = tree.getroot() #获取根节点(根对象)
print(root.attrib) #获取根对象的属性(这里为空)
for i in root: #遍历根对象,得到子节点(对象)
print(i.attrib) #获取子节点的属性
print(i.attrib['name']) #取出value
#text方法(获取标签对象的实际内容)
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson.xml") root = tree.getroot() for i in root: for j in i: print(j.text) #获取标签对象的内容
#root.iter()方法 :遍历获取指定对象
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson.xml") root = tree.getroot() for i in root.iter('year'): #遍历root,只拿出year
print(i.tag,i.text) #打印标签名和内容
#tree.write() : 将整个xml 树写入新文件(修改操作)
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson.xml") root = tree.getroot() for i in root.iter('year'): i.text = '修改的标签值' #这里都只是在内存中修改
i.set('这是标签属性名','这是标签属性值') tree.write('xml_new.xml',encoding='utf8') #修改后写入新文本
#findall()-->找多个对象;find()找单个对象;root.remove-->删除对象
import xml.etree.ElementTree as ET tree = ET.parse("xml_lesson.xml") root = tree.getroot() for i in root.findall('country'): #找出root下所有country对象
rank = int(i.find('rank').text) #找到country对象中的rank的值
if rank > 50 : #删除rank大于50的country对象
root.remove(i) tree.write('xml_new.xml',encoding='utf8')
#创建xml文档
import xml.etree.ElementTree as ET namelist = ET.Element('namelist') #创建主节点
name = ET.SubElement(namelist,'name',attrib={'这是属性名':'这是属性值'}) #创建副节点
name.text='这是副节点值' et=ET.ElementTree(namelist) #生成文档对象(那颗树)
et.write('newxml.xml',encoding='utf8',xml_declaration=True)
#re模块(正则表达式)
#用于处理字符串,模糊匹配
#re是一种小型的、高度专业化的编程语言(由C语言编写),任何编程语言都有
#正则的核心:元字符 . ^ $ + ? {} [] | () \
#re.findall() -->匹配所有满足条件的内容,但不能有重叠,如下应用
#通配符 .
#可以匹配任何字符,除了换行符\n,一个 . 代表一个字符
import re print(re.findall('a...b','adfadfjblakjdb'))
# ^ -->以什么开头
print(re.findall('^a..b','adfbdfjblakj'))
# $ -->以什么结尾
print(re.findall('a..b$','adfbdfjblakjb'))
#四个重复匹配符号
# * 匹配靠近的字符0到无穷次(匹配的字符可以一个都没有,也就是匹配0次)
# + 匹配靠近的字符1 到 无穷次(匹配的字符必须有一个,也就是匹配1次)
print(re.findall('abc*','aaaabdd')) #匹配到'ab' print(re.findall('abc+','aaaabdd')) #未匹配到
#以上* + ?都为贪婪匹配,即按最多匹配最多的次数,后面加?改成惰性匹配(通用,{}后加也行)
# ? 匹配0或1 次
# {} 匹配次数由你定
print(re.findall('abc?','aaaabccccdd')) print(re.findall('abc{0,1}','aaaabcccccccdd')) #相当于 ? print(re.findall('abc{0,}','aaaabcccccccdd')) #匹配0到无穷次 ,相当于 * print(re.findall('abc{5}','aaaabcccccccdd')) #匹配5次
print(re.findall('abc{1,4}?','aaaabcccdd')) #改为惰性匹配
#字符集 [] 里面没有特殊符号(- ^ \ 除外),所有都为字符
# - 代表XXX到XXX
print(re.findall('abc[cd]','aaaabcccdd')) #[] 里代表c或d print(re.findall('abc[cd xb]','abcxxabccdcdd')) print(re.findall('x[a-z]','xaaaabcccdd')) #[a-z] 代表匹配的一个字符 ,a-z 代表 a到z的字母 , print(re.findall('x[a-z]*','xaaaabcccdd666'))
# ^ 代表 非
print(re.findall('x[^a-z]*','xaaaabcccdd666'))
# \ 转译符 (放在字符之前代表把一个元字符变成普通字符,或者把普通字符变得有意义)
\d 匹配所有数字 0到9
\D 匹配所有非数字字符
\s 匹配任何空白字符
\S 匹配任何非空白字符
\w 匹配任何字母数字字符(包括_)
\W匹配任何非字母数字
\b 匹配一个特殊字符边界
import re print(re.findall('I\\b','111 I am 222I333')) #\b代表匹配的特殊字符(如空格)或边界字符
#这里写\\b(\\代表去掉了python解释器里\的特殊意义,变为一个普通的\)是因为在python解释器中\b已有特殊意义,与re模块的重复了
print(re.findall(r'I\b','111 I am 222I333')) #这里的r 代表对于后面的字符串,python解释器不做任何转译,于是就用来re模块里的转译
#把元字符变为普通字符
import re print(re.findall('a\\\\c','a\c')) #首先python解释器里,\\\\转译成两个普通的\\,然后在re模块里,\\转译为一个普通\
#匹配结果为['a\\c'],因为匹配到的是re里的\,到python解释器里,又转译为\\
print(re.findall(r'a\\c','a\c')) #或者用r不让python解释器做转译
#取出最里面括号的内容
print(re.findall('\([^()]*\)','12+5*(7-6*(3-1))'))
# () 代表分组 | 代表或
print(re.findall('ab|c','abcdac')) # | 代表 或 (ab 或 c)
print(re.findall('(abc)+','abcccc')) # 只匹配到abc
#search 方法
#区别与findall,同样是查找,但search只匹配一次(找到第一个匹配的),且返回的是一个对象
a = re.search('\d+','adsf213dfa4213dd') #返回 <re.Match object; span=(4, 7), match='213'>
print(a.group()) #取出对象内容
#分组
b = re.search('(?P<name>[a-z]+)(?P<age>\d+)','alex30ssy18') #固定写法(?P<组名>匹配的内容) 用于把匹配的内容分组
print(b.group('name'),b.group('age')) #取出匹配内容里的指定组
# match 方法
#从开始进行匹配,相当于search里加 ^
print(re.match('\d','adf213')) #匹配不到
#split 方法
#以指定字符串分隔
print(re.split('ab','adffabdfsdsf')) #以指定字符串分隔
#sub、subn(替换完并把替换次数写出) 方法
#替换
print(re.sub('\d+','B','adf23123adfs')) #sub('被替换的字符串(找到所有的)','替换的内容','总的内容')
#如果想替换指定次数,sub()第四个参数写上次数
print(re.sub('\d','B','adf23123adfs',1))
#compile 方法
func=re.compile('\d+') #将匹配需求保存成对象
print(func.findall('adsf231fa3'))
#finditer 方法
a=re.finditer('\d+','213dsfa2') #跟findall一模一样,只是返回的不是列表而是迭代器
print(a.__next__().group())
#小补充
import re print(re.findall('www\.(163)\.com','123www.163.comfadsf')) #用()分组后,解释器会默认觉得你所关注的内容为组的内容,于是只返回组的值(如这里是163)
print(re.findall('www\.(?:163)\.com','123www.163.comfadsf')) #()里的内容前面加上?:可以去掉优先级 #还有如下例子
print(re.findall('123','123123123')) #['123', '123', '123']
print(re.findall('(123)+','123123123')) #['123'] 括号的优先级认为你只关注与括号内的123,于是只显示123
print(re.findall('(?:123)+','123123123')) #['123123123']
#利用正则实现eval进行四则运算的功能(重要!!!!!!!!!!!!!) 如:
# '(5 + 40.1 / 5 * ((6+4*4) * 5 - (5+4))+6*7)*2/5+1'
import re def calc(a): a = a.replace(' ','') #消去空格 b = re.findall('[^+\-]+[*/]+[^+\-]+',a) #查找乘除部分 num = [] for i in b : d = re.split('[*/]',i) e = re.findall('[*/]',i) for j in e : if j == '*': d[1] = (float(d[0]))*(float(d[1])) del d[0] elif j == '/' : pass d[1] = (float(d[0]))/(float(d[1])) del d[0] num.append(d[0]) A = re.split('[+\-]',a) for k,l in enumerate(A) : if re.findall('[*/]+',l) : A[k] = num[0] del num[0] else : A[k]=float(A[k]) n = re.findall('[+\-]+', a) for o in n : if o == '+' : A[1] = A[0]+A[1] del A[0] elif o == '-' : A[1] = A[0]-A[1] del A[0] return [A[0]] def eval_new(x): x = x.replace(' ', '') if x.count('(') == x.count(')') and (not re.findall('[+\-*/]{2,}',x)) and re.findall('[\d)]{1}',x[-1]): while True : a = re.findall('\([^()]+\)',x) if not a : print(calc(x)[0]) break else: for num,i in enumerate(a) : b = re.sub('[()]','',i) c = calc(b) x = x.replace(i,str(c[0])) else : print('表达式有误') print(eval('(5 + 40.1 / 5 * ((6+4*4) * 5 - (5+4))+6*7)*2/5+1')) #343.808 eval_new('(5 + 40.1 / 5 * ((6+4*4) * 5 - (5+4))+6*7)*2/5+1') #343.808
#logging模块 (日志模块)
#分为五个级别,debug、info、warning、error、critical (级别依次升高)
#指定那个级别,就把那个级别之上的(包括自己)给显示出来(默认显示如下)
#basicConfig设置
import logging logging.basicConfig( level=logging.DEBUG, # 设定显示级别为debug,注意大写,不设置默认为warning级别
filename='logging.log', # 设置日志信息保存文件,如果不写这项则输出到屏幕
filemode='w', format='%(asctime)s %(lineno)d %(message)s %(filename)s' #1、内容改为asctime时间2、输出显示各级别信息的行号3、日志信息
) #4、该代码文本的文件名
logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
#以上执行结果如下
#format参数
#Logger
def logger_func(): #定义成函数,方便调用(可以存成文本再别的文件中调用)
logger=logging.getLogger() #指定功能的对象
fh=logging.FileHandler('文件名') #向文件输出
ch=logging.StreamHandler() #向屏幕输出
fm=logging.Formatter('%(asctime)s %(message)s') #格式化输出,可以任意制定格式
#调用以上功能
fh.setFormatter(fm) #获取fm的格式,不写此行代码就以默认的格式输出
ch.setFormatter(fm) #同上 logger.setLevel('DEBUG') #设置级别,要大写
logger.addHandler(fh) #调用fh的功能 logger.addHandler(ch) #调用ch的功能 return logger logger=logger_func() #把函数的返回值logger赋值给logger
logger.debug('debug message') logger.info('info message') logger.warning('warning message') logger.error('error message') logger.critical('critical message')
#逻辑图如下
#注意!!!如果要设置多个子对象,命名一定不能重复,以下例子说明(错误示范)
import logging logger1=logging.getLogger('name') #得到一个子对象,并命名为name(不写默认为root),注:创建子对象的子对象用 name.son
logger2=logging.getLogger('name') #这里logger1 logger2重名了
ch=logging.StreamHandler() logger1.setLevel('CRITICAL') logger2.setLevel('WARNING') #因为logger1 logger2重名,所以第二个设置直接覆盖了第一个设置
logger1.addHandler(ch) logger2.addHandler(ch) logger1.debug('debug message') #输出logger1设置下的日志
logger1.info('info message') logger1.warning('warning message') logger1.error('error message') logger1.critical('critical message') logger2.debug('debug message') #输出logger2设置下的日志
logger2.info('info message') logger2.warning('warning message') logger2.error('error message') logger2.critical('critical message')
#父对象输出时,会把所有子对象也输出
import logging logger1=logging.getLogger() logger2=logging.getLogger('son') logger3=logging.getLogger('son.son') fh=logging.FileHandler('文件名') ch=logging.StreamHandler() logger1.setLevel('CRITICAL') logger2.setLevel('ERROR') logger3.setLevel('WARNING') logger1.addHandler(fh) logger2.addHandler(fh) logger3.addHandler(fh) logger1.addHandler(ch) # logger2.addHandler(ch) # logger3.addHandler(ch)
logger1.debug('11111debug message') logger1.info('1111info message') logger1.warning('1111warning message') logger1.error('1111error message') logger1.critical('1111critical message') logger2.debug('2222debug message') logger2.info('222info message') logger2.warning('2222warning message') logger2.error('2222error message') logger2.critical('222critical message') logger3.debug('3333debug message') logger3.info('333info message') logger3.warning('333warning message') logger3.error('333error message') logger3.critical('333critical message')
#如果没有 输出到文件或屏幕,则默认输出到屏幕。若不想输出到屏幕,则需要输出到文件里并不写输出到屏幕的相应代码才行!!!!!!!!!!!!!!!!!!!!