常用模块

os模块

os模块是与操作系统交互的一个接口,它提供的功能多与工作目录,路径,文件等相关

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

sys模块

sys模块是与python解释器交互的一个接口

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

 time模块

与时间相关

 1 # 格式化时间 ---->  结构化时间
 2 ft = time.strftime('%Y/%m/%d %H:%M:%S')
 3 st = time.strptime(ft,'%Y/%m/%d %H:%M:%S')
 4 print(st)
 5 # 结构化时间 ---> 时间戳
 6 t = time.mktime(st)
 7 print(t)
 8 
 9 # 时间戳 ----> 结构化时间
10 t = time.time()
11 st = time.localtime(t)
12 print(st)
13 # 结构化时间 ---> 格式化时间
14 ft = time.strftime('%Y/%m/%d %H:%M:%S',st)
15 print(ft)
View Code
 1 #结构化时间 --> %a %b %d %H:%M:%S %Y串
 2 #time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串
 3 >>>time.asctime(time.localtime(1500000000))
 4 'Fri Jul 14 10:40:00 2017'
 5 >>>time.asctime()
 6 'Mon Jul 24 15:18:33 2017'
 7 
 8 #时间戳 --> %a %d %d %H:%M:%S %Y串
 9 #time.ctime(时间戳)  如果不传参数,直接返回当前时间的格式化串
10 >>>time.ctime()
11 'Mon Jul 24 15:19:07 2017'
12 >>>time.ctime(1500000000)
13 'Fri Jul 14 10:40:00 2017' 
14 
15 t = time.time()
16 ft = time.ctime(t)
17 print(ft)
18 
19 st = time.localtime()
20 ft = time.asctime(st)
21 print(ft)
View Code
 1 mport time
 2 true_time=time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S'))
 3 time_now=time.mktime(time.strptime('2017-09-12 11:00:00','%Y-%m-%d %H:%M:%S'))
 4 dif_time=time_now-true_time
 5 struct_time=time.gmtime(dif_time)
 6 print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1,
 7                                        struct_time.tm_mday-1,struct_time.tm_hour,
 8                                        struct_time.tm_min,struct_time.tm_sec))
 9 
10 计算时间差
View Code

 logging模块

函数式简单配置

import logging  
logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')

灵活配置日志级别,日志格式,输出位置:

import logging  
logging.basicConfig(level=logging.DEBUG,  
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
                    datefmt='%a, %d %b %Y %H:%M:%S',  
                    filename='/tmp/test.log',  
                    filemode='w')  
  
logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')
 1 logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
 2 
 3 filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
 4 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
 5 format:指定handler使用的日志显示格式。
 6 datefmt:指定日期时间格式。
 7 level:设置rootlogger(后边会讲解具体概念)的日志级别
 8 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
 9 
10 format参数中可能用到的格式化串:
11 %(name)s Logger的名字
12 %(levelno)s 数字形式的日志级别
13 %(levelname)s 文本形式的日志级别
14 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
15 %(filename)s 调用日志输出函数的模块的文件名
16 %(module)s 调用日志输出函数的模块名
17 %(funcName)s 调用日志输出函数的函数名
18 %(lineno)d 调用日志输出函数的语句所在的代码行
19 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
20 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
21 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
22 %(thread)d 线程ID。可能没有
23 %(threadName)s 线程名。可能没有
24 %(process)d 进程ID。可能没有
25 %(message)s用户输出的消息
View Code

标配版:

# import logging
#
# # 创建一个logging对象
# logger = logging.getLogger()
#
# # 创建一个文件对象
# fh = logging.FileHandler('标配版.log', encoding='utf-8')
#
# # 创建一个屏幕对象
# sh = logging.StreamHandler()
#
# # 配置显示格式
# formatter1 = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
# formatter2 = logging.Formatter('%(asctime)s %(message)s')
# fh.setFormatter(formatter1)
# sh.setFormatter(formatter2)
#
# logger.addHandler(fh)
# logger.addHandler(sh)
#
# # 总开关
# logger.setLevel(10)
#
# fh.setLevel(10)
# sh.setLevel(40)
#
# logging.debug('调试模式')  # 10
# logging.info('正常模式')  # 20
# logging.warning('警告信息')  # 30
# logging.error('错误信息')  # 40
# logging.critical('严重错误信息')  # 50
View Code

旗舰版:

"""
logging配置
"""

import os
import logging.config

# 定义三种日志输出格式 开始

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'

# 定义日志输出格式 结束

logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录

logfile_name = 'all2.log'  # log文件名

# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
    os.mkdir(logfile_dir)

# log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name)

# log配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
    },
    'filters': {},
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': logfile_path,  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },
    },
}


def load_my_logging_cfg():
    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
    logger = logging.getLogger(__name__)  # 生成一个log实例
    logger.info('It works!')  # 记录该文件的运行状态

if __name__ == '__main__':
    load_my_logging_cfg()

logger配置文件
View Code

注意注意注意:

#1、有了上述方式我们的好处是:所有与logging模块有关的配置都写到字典中就可以了,更加清晰,方便管理


#2、我们需要解决的问题是:
    1、从字典加载配置:logging.config.dictConfig(settings.LOGGING_DIC)

    2、拿到logger对象来产生日志
    logger对象都是配置到字典的loggers 键对应的子字典中的
    按照我们对logging模块的理解,要想获取某个东西都是通过名字,也就是key来获取的
    于是我们要获取不同的logger对象就是
    logger=logging.getLogger('loggers子字典的key名')

    
    但问题是:如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key   
 'loggers': {    
        'l1': {
            'handlers': ['default', 'console'],  #
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },
        'l2: {
            'handlers': ['default', 'console' ], 
            'level': 'DEBUG',
            'propagate': False,  # 向上(更高level的logger)传递
        },
        'l3': {
            'handlers': ['default', 'console'],  #
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },

}

    
#我们的解决方式是,定义一个空的key
    'loggers': {
        '': {
            'handlers': ['default', 'console'], 
            'level': 'DEBUG',
            'propagate': True, 
        },

}

这样我们再取logger对象时
logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=''的配置

如何拿到logger对象的详细解释
View Code

re模块

1.什么是正则表达式

一套规则-匹配字符串的

2.正则 能作什么?

 检测一个输入的字符串是否合法   --web开发项目   表单验证

  +用户输入一个内容的时候,我们要提前做检测

  +能够提高程序的效率并且减轻服务器的压力

从一个大文件中找到所有符合规则的内容  -- 日志分析\爬虫

  +能够高效的从一大段文字中快速找到符合规则的内容

正则规则

所有的规则中的字符就可以刚好匹配到字符串的内容

字符组:[字符组]

在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示字符分为很多类,比如数字、字母、标点等等。假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。

描述的是一个位置上能出现的所有可能性:

- 接受范围,可以描述多个范围,连着写就可以了
- [abc]   一个中括号只表示一个字符位置,匹配a或者b或者c
- [0-9]   根据ascii进行范围的比对
- [a-z]
- [A-Z]
- [a-zA-Z]大小写
- [0-9a-z]
- [0-9a-zA-Z]
View Code

在正则表达式中能够帮助我们表示匹配的内容的符号都是正则中的 元字符:

- [0-9]       -->   \d      表示匹配一位任意数字   digit
- [0-9a-zA-Z]    -->     \w  表示匹配数字字母下划线    word
- 空格    
- tab    -->     \t
- enter回车  -- >     \n
- 空格,tab和回车    -->   \s    表示所有空白   包括空格   tab和回车
- \W   非数字字母下划线
- \D    非数字
- \S   非空白
- [\d]     \d
- [\d\D]       '[\w\W]'     [\s\S]    表示所有
- .    匹配除了换行符之外的所有
- [^\d]    匹配所有的非数字
- [^1]     匹配所有的非数字
- ^    匹配一个字符串的开始
- $    匹配一个字符串的结尾
- a 表达式|b表达式         匹配a或者b表达式中的内容,如果匹配a成功了,不会继续和b匹配
  所以,如果两个规则有重叠部分,总是把长的放在前面
- ()      约束    |    描述的内容的范围问题
View Code

记忆元字符: 都是表示能匹配那些内容,一个元字符总是表示一个字符位置上的内容

量词:

- {n}    表示匹配n次
- {n,}    表示匹配至少n次
- {n,m}  表示至少匹配n次,至多m次
- ?  表示匹配0次或1次{0,1}
- +表示1次或多次    {1,}
- *表示0次或多次    {0,}
View Code

贪婪匹配:在量词范围允许的情况下,尽量多的匹配内容,.*x 表示匹配任意字符 任意多次数 遇到最后一个x才停下来

非贪婪(惰性)匹配:  .*?x 表示匹配任意字符 任意多次数 但是一旦遇到x就停下来

转义符:原本有特殊意义的字符,到了表达它本身的意义的时候,需要转义,有一些有特殊意义的内容,放在字符组中,会取消它的特殊意义,[().*+?] 所有的内容在字符组中会取消它的特殊意义,[a'\'-c] -在字符组中表示范围,如果不希望它表示范围,需要转义,或者放在字符组的最前面或最后面

re模块的常用方法

import re

ret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']

ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

ret = re.match('a', 'abc').group()  # 同search,不过尽在字符串开始处进行匹配
print(ret)
#结果 : 'a'

ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)  # ['', '', 'cd']

ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4

ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)

obj = re.compile('\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  #结果 : 123

import re
ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果
View Code

注意:

1.findall的优先级查询

import re

ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['oldboy']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可

ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['www.oldboy.com']
View Code

2.split的优先级查询

ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']

ret=re.split("(\d+)","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']

#在匹配部分加上()之后所切出的结果是不同的,
#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
#这个在某些需要保留匹配部分的使用过程是非常重要的。
View Code

 

posted @ 2019-06-29 14:54  欢如平生  阅读(148)  评论(0编辑  收藏  举报