qpython下载parsel模块_Python常用模块

本文详细介绍了Python的四个常用模块:optparse用于命令行选项解析,configparser处理配置文件,logging提供日志记录功能,zipfile则用于处理zip文件的压缩与解压。通过示例代码和实战应用,深入讲解了各模块的使用方法和关键功能。
摘要由CSDN通过智能技术生成

阅读目录

一、optparse

二、configparser

三、logging

四、zipfile

一、optparse

1 模块介绍

optparse是一个比旧的getopt模块更方便、灵活和强大的解析命令行选项的库

2 简单示例

编辑test.py

from optparse import OptionParser

# 实例对象

parser = OptionParser()

# 添加参数 -f 指定一个文件名称

parser.add_option("-f", "--file", dest="filename",

help="write report to FILE", metavar="FILE")

parser.add_option("-q", "--quiet",

action="store_false", dest="verbose", default=True,

help="don't print status messages to stdout")

# 解析参数

(options, args) = parser.parse_args()

print("options:", options) # {'filename': 'aaa', 'verbose': False}

print("args:", args) # ['bbb']

# 终端输入:python test.py -f aaa -q bbb

3 参数介绍

action 解析选项时执行的动作:

'store'——选项有一个参数需要读取和保存,如果没有任何显示指定动作,这就是默认动作

'store_const'——选项不带任何参数,但是当遇到选项时,就会保存const关键字参数指定的常量值

'stone_true'——解析选项时,保存的是BOOL值

'store_false'——解析选项时,保存的是BOOL值

'append'——选项有一个参数,解析时被附加到一个列表

'count'——选项不带任何参数,但是保存一个计数器,遇到参数,计数器的值就会增加

'callback'——遇到选项时,调用callback关键字指定的一个回调函数

'help'——解析选项时打印一条帮助消息

'version'——解析选项是获取指定文件版本

callback 指定遇到选项时候调用的回调函数 callback(option,opt_str,value,parse,*rags,**kwarg)

choices 指定所有可能的选项值的字符串列表,当一个选项只有一组有限的值时候使用

const 通过store_const动作保存的常量值

default 默认值None

dest 设置用于保存解析期间选项值的属性名称

help 这个特定选项的帮助文档

metavar 指定打印帮助文本时使用的选项参数的名称

nargs 为需要参数的动作指定选项参数的数量

type 指定选项的类型

4 parser对象常用方法

parser.disable_interspersed_args() #不接受简单选项和位置参数的混合使用

parser.enable_interspersed_args() #选项与位置参数可以混合使用

parser.parse_args() #解析命令行选项,并返回一个元组(options,args)options包含所有选项的值得对象,args是所有余下位置参数的列表

parser.set_defaults() #设置特定选项目的的默认值

5 实战应用

class SysEntrance(object):

"""系统入口"""

def __init__(self):

# 创建OptionParser类对象

self.parser = optparse.OptionParser()

self.add_option()

self.options, self.args = self.parser.parse_args() # 获取格式化获取的信息

def add_option(self):

"""

添加选项

"""

self.parser.add_option("-d", "--dp", dest="path", metavar="PROFILE") # 目录

self.parser.add_option("-t", "--et", dest="type", choices=['1', '2', '3']) # 执行类型

self.parser.add_option("-b", "--build", action="callback", callback=self.vararg_callback, dest="build",

help="build", metavar="PROFILE")

self.parser.add_option("-g", "--debug", action="store_true", dest="debug",

help="build with debug symbols, affects only full build")

def vararg_callback(self, option, opt_str, value, parser):

"""

调用parser.parse_args()触发回调函数, 可以实现对选项参数值的加工

:param option: optparse.Option类

:param opt_str: 选项参数 -b/--build

:param value: //可以留言告诉我是什么值

:param parser: optparse.OptionParser对象

:return:

"""

assert value is None

value = []

for arg in parser.rargs:

# stop on --foo like options

if arg[:2] == "--" and len(arg) > 2:

break

# stop on -a, but not on -3 or -3.0

if arg[:1] == "-" and len(arg) > 1:

break

value.append(arg)

del parser.rargs[:len(value)]

# 重新设置dest对应的值

setattr(parser.values, option.dest, value)

def check_option(self):

"""检查option选项"""

if self.options.path and not os.path.exists(self.options.__dict__.get('path')):

return "选项[path]指定错误 >> 请指定有效的文件路径"

def run(self):

"""根据配置信息进入不同的业务层"""

err = self.check_option()

if err:

return None, err

# 业务层

if self.options.debug:

global DEBUG

DEBUG = True

if self.options.type:

return func(), None

DEBUG = False

def func():

global DEBUG

if DEBUG:

print(1111)

else:

print(2222)

if __name__ == "__main__":

_, err = SysEntrance().run()

print(err)

二、configparser

1 模块介绍

configparser库实现了一种基本的配置文件解析语言,它提供了一种类似于microsoft windows ini文件的结构。

2 简单示例

import configparser

parser = configparser.ConfigParser()

parser.read_dict({'section1': {'key1': 'value1',

'key2': 'value2',

'key3': 'value3'},

'section2': {'keyA': 'valueA',

'keyB': 'valueB',

'keyC': 'valueC'},

'section3': {'foo': 'x',

'bar': 'y',

'baz': 'z'}

})

print(parser.sections())

# ['section1', 'section2', 'section3']

print([option for option in parser['section3']])

# ['foo', 'bar', 'baz']

3 常用介绍

3.1 读取配置文件

配置文件pro.ini

# 注释1

; 注释2

# DEFAULT为其它sections提供默认值

[DEFAULT]

a = 45

[Common]

# 引用同一节点

home_dir: /Users

my_dir: %(home_dir)s/lumberjack

my_pictures: %(my_dir)s/Pictures

[section1]

k1 = v1

k2:v2

# 引用不同节点 -> python3.8

path: ${Common:my_dir}/Library/Frameworks/

[section2]

k1 = v1

# 空值

k2 =

k3 = true

k4 = 22.05

Note1:在配置文件中%是唯一需要转义的字符,10%可使用10%%代替

Note2:key值不区分大小写,都会被转化为小写

import configparser

config=configparser.ConfigParser()

config.read('pro.ini')

#查看所有的标题

res=config.sections()

print(res) # ['Common', 'section1', 'section2']

#查看标题section1下所有key=value的key

options=config.options('section1')

print(options) #['k1', 'k2', 'path', 'a']

#查看标题section2下所有key=value的(key,value)格式

item_list=config.items('section2')

print(item_list) #[('a', '45'), ('k1', 'v1'), ('k2', '')]

#查看标题section1下k1的值=>字符串格式

val=config.get('section1','k1')

print(val) #v1

#查看标题section1下a的值=>整数格式

val1=config.getint('section1','a')

print(val1) #45

#查看标题section2下k3的值=>布尔值格式

val2=config.getboolean('section2','k3')

print(val2) #True

#查看标题section2下k4的值=>浮点型格式

val3=config.getfloat('section2','k4')

print(val3) #22.05

#删除整个标题section2

config.remove_section('section2')

#删除标题section1下的某个k1和k2

config.remove_option('section1','k1')

config.remove_option('section1','k2')

#判断标题section1下是否有k1

print(config.has_option('section1','k1'))

#判断是否存在某个标题

print(config.has_section('section1'))

#添加一个标题

config.add_section('Paths')

#在标题Paths下添加p1=/root,p2=/tmp的配置, 注意value值必须为字符串

config.set('Paths','p1','/root')

config.set('Paths','p2','/tmp')

#最后将修改的内容写入文件,完成最终的修改

config.write(open('pro.ini','w'))

4 实战应用

4.1 key值区分大小写

from configparser import ConfigParser

class NewConfigParser(ConfigParser):

def __init__(self, defaults=None):

ConfigParser.__init__(self, defaults=defaults)

"""复写方法实现key值区分大小写"""

def optionxform(self, optionstr):

return optionstr

4.2 实现配置文件启动系统

借助上面optparse的知识,实现一个可以通过命令行调用配置文件启动系统的功能

class ExecuteConfig(File):

"""执行器配置文件"""

def __init__(self):

self.configParser = ReConfigParser()

def analysis(self, filename):

"""解析配置文件"""

filepath = self.join_path(self.base_dir, filename)

if not self.is_exist(filepath):

return None, "配置文件异常 >> 配置文件不存在"

self.configParser.read(filepath, encoding='utf-8')

items = self.configParser.items('execute') # 规定解析头必须为execute

return items, None

class Options(object):

def __init__(self):

self.parser = OptionParser()

self.add_option()

self.options_dict = dict() # 保存选项解析结果

self.options, self.args = self.parser.parse_args() # 获取格式化获取的信息

self.pretreatment()

def add_option(self):

"""

添加选项

:return:

"""

self.parser.add_option("--ini", dest="ini") # 启动配置

'''

自定制命令

'''

def pretreatment(self):

"""预处理"""

if self.options.ini:

# 启动文件

config = ExecuteConfig()

items, err = config.analysis(self.options.ini)

if err:

raise ValueError(err)

for item in items:

if hasattr(self, f'handle_{item[0]}'):

err = getattr(self, f'handle_{item[0]}')(item[1])

if err:

raise ValueError(err)

else:

raise ValueError(f"选项解析失败 >> 无效配置参数【{item[0]}】")

def handle_ini(self, args):

pass

'''处理选项操作逻辑'''

def handle_logType(self, args):

if not args:

reutrn "选项错误 >> logType不能为空"

self.options_dict.update({"logType": args})

def handle_logLevel(self, args):

if args:

self.options_dict.update({"logLevel": args})

def handle_logTo(self, args):

if args:

self.options_dict.update({"logTo": args})

接下来在系统入口实例化Options()类就可以实现配置文件启动了

三、logging

1 模块介绍

logging库提供python程序日志记录功能

2 简单示例

import logging

logging.debug("debug 日志")

logging.info("info 日志")

logging.warning("warning 日志")

logging.error("error 日志")

logging.critical("critical 日志")

输出结果:

WARNING:root:warning 日志

ERROR:root:error 日志

CRITICAL:root:critical 日志

3 logging源码分析及流程图

3.1 源码分析

3.2 流程图

4 基本使用

4.1 basicConfig

可选的参数如下表所示:

示例代码:

# stream设置文件流,繁殖中文乱码

f = open('test.log', 'w', encoding='utf-8')

logging.basicConfig(stream=f, format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)

logging.debug("debug 日志")

logging.info("info 日志")

logging.warning("warning 日志")

logging.error("error 日志")

logging.critical("critical 日志")

f.close()

生成日志:

23-18-2019 00:18:41 root:DEBUG:debug 日志

23-18-2019 00:18:41 root:INFO:info 日志

23-18-2019 00:18:41 root:WARNING:warning 日志

23-18-2019 00:18:41 root:ERROR:error 日志

23-18-2019 00:18:41 root:CRITICAL:critical 日志

当发生异常时,直接使用无参数的 debug()、info()、warning()、error()、critical() 方法并不能记录异常信息,需要设置 exc_info 参数为 True 才可以,或者使用 exception() 方法,还可以使用 log() 方法,但还要设置日志级别和 exc_info 参数。

import logging

logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)

a = 5

b = 0

try:

c = a / b

except Exception as e:

# 下面三种方式三选一,推荐使用第一种

logging.exception("Exception occurred")

logging.error("Exception occurred", exc_info=True)

logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)

4.2 自定义Logger

getLogger函数获取一个Logger对象,使用给定名称对该函数的所有调用都返回相同的记录器实例。这意味着记录器实例永远不需要在应用程序的不同部分之间传递。

Logger 对象可以设置多个 Handler 对象和 Filter 对象,Handler 对象又可以设置 Formatter 对象。Formatter 对象用来设置具体的输出格式,常用变量格式如下表所示:

import logging

import logging.handlers

logger = logging.getLogger("logger")

#设置控制台输出

handler1 = logging.StreamHandler()

#设置文件输出

handler2 = logging.FileHandler(filename="test.log")

#设置输出等级,输出时会和设置的最大值比较

logger.setLevel(logging.DEBUG)

handler1.setLevel(logging.WARNING)

handler2.setLevel(logging.DEBUG)

#添加格式化输出

formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")

handler1.setFormatter(formatter)

handler2.setFormatter(formatter)

#自定义logger对象添加handler处理对象

logger.addHandler(handler1)

logger.addHandler(handler2)

logger.debug("debug 日志")

logger.info("info 日志")

logger.warning("warning 日志")

logger.error("error 日志")

logger.critical("critical 日志")

终端输出:

2019-11-23 00:38:24,030 logger WARNING warning 日志

2019-11-23 00:38:24,030 logger ERROR error 日志

2019-11-23 00:38:24,030 logger CRITICAL critical 日志

test.log:

2019-11-23 00:38:24,030 logger DEBUG debug 日志

2019-11-23 00:38:24,030 logger INFO info 日志

2019-11-23 00:38:24,030 logger WARNING warning 日志

2019-11-23 00:38:24,030 logger ERROR error 日志

2019-11-23 00:38:24,030 logger CRITICAL critical 日志

NOTE:创建了自定义的 Logger 对象,就不要在用 logging 中的日志输出方法了,这些方法使用的是默认配置的 Logger 对象,否则会输出的日志信息会重复。

4.2 Logger配置

4.2.1 字典格式配置

import logging.config

config = {

'version': 1,

'formatters': {

'simple': {

'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',

},

# 其他的 formatter

},

'handlers': {

'console': {

'class': 'logging.StreamHandler',

'level': 'DEBUG',

'formatter': 'simple'

},

'file': {

'class': 'logging.FileHandler',

'filename': 'logging.log',

'level': 'DEBUG',

'formatter': 'simple'

},

# 其他的 handler

},

'loggers':{

'StreamLogger': {

'handlers': ['console'],

'level': 'DEBUG',

},

'FileLogger': {

# 既有 console Handler,还有 file Handler

'handlers': ['console', 'file'],

'level': 'DEBUG',

},

# 其他的 Logger

}

}

logging.config.dictConfig(config)

StreamLogger = logging.getLogger("StreamLogger")

FileLogger = logging.getLogger("FileLogger")

4.2.2 配置文件中获取配置信息

logger.ini文件

[loggers]

keys=root,sampleLogger

[handlers]

keys=consoleHandler

[formatters]

keys=sampleFormatter

[logger_root]

level=DEBUG

handlers=consoleHandler

[logger_sampleLogger]

level=DEBUG

handlers=consoleHandler

qualname=sampleLogger

propagate=0

[handler_consoleHandler]

class=StreamHandler

level=DEBUG

formatter=sampleFormatter

args=(sys.stdout,)

[formatter_sampleFormatter]

format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

引用:

import logging.config

logging.config.fileConfig(fname='logger.ini', disable_existing_loggers=False)

logger = logging.getLogger("sampleLogger")

5 实战应用

5.1 日志文件按照时间划分或者按照大小划分

# 每隔 1000 Byte 划分一个日志文件,备份文件为 3 个

file_handler = logging.handlers.RotatingFileHandler("test.log", mode="w", maxBytes=1000, backupCount=3, encoding="utf-8")

# 每隔 1小时 划分一个日志文件,interval 是时间间隔,备份文件为 10 个

handler2 = logging.handlers.TimedRotatingFileHandler("test.log", when="H", interval=1, backupCount=10)

5.2 flask logging配置

project_name/conf/config.py

class BaseConfig(object):

# SECRET_KEY = os.environ.get('SECRET_KEY') or 'awklihdytcbmoq'

SECRET_KEY = os.urandom(24)

PERMANENT_SESSION_LIFETIME = timedelta(days=7)

PROJECT = '伟大的项目'

VERSION = 'v1.0'

API_VERSION = 'api/v1.0'

# 指定json编码格式 如果为False 就不使用ascii编码,

JSON_AS_ASCII = False

# 指定浏览器渲染的文件类型,和解码格式;

JSONIFY_MIMETYPE = "application/json;charset=utf-8"

DEBUG = True

TESTING = False

PROD = False

# QQ邮箱配置

MAIL_DEBUG = True # 开启debug,便于调试看信息

MAIL_SUPPRESS_SEND = False # 发送邮件,为True则不发送

MAIL_SERVER = 'smtp.qq.com' # 邮箱服务器

MAIL_PORT = 465 # 端口

MAIL_USE_SSL = True # 重要,qq邮箱需要使用SSL

MAIL_USE_TLS = False # 不需要使用TLS

MAIL_USERNAME = '4xxxxxxxx@qq.com' # 填邮箱

MAIL_PASSWORD = 'xcxxxxxxxxx' # 填授权码 -> 百度怎么获取

FLASK_MAIL_SENDER = 'xxxxxxxx@qq.com' # 邮件发送方

FLASK_MAIL_SUBJECT_PREFIX = '{伟大的项目} - 错误日志' # 邮件标题

MAIL_DEFAULT_SENDER = '4xxxxxxxx@qq.com' # 填邮箱,默认发送者

class TestEnvConfig:

pass

class ProdEnvConfig:

pass

class DevConfig:

pass

project_name/init.py

def create_app(config=None, app_name=None, blueprints=None):

"""Create Flask app"""

if app_name is None:

app_name = Configs.BaseConfig.PROJECT

app = Flask(app_name, static_folder='xxx/static',

template_folder='xxx/tempaltes')

configure_app(app, config)

configure_logging(app)

def configure_app(app, config):

"""Configure register app """

import project_name.conf.config as Configs

# 这里可以用变量设置导入开发环境/测试环境/生产环境不同配置

app.config.from_object(Configs.BaseConfig)

def configure_logging(app):

"""Configure file(info) and email(error) logging."""

if app.debug or app.testing:

# Skip debug and test mode.

return

import logging,os

from logging.handlers import SMTPHandler

# Set info level on logger, which might be overwritten by handers.

app.logger.setLevel(logging.INFO) # 可以设置不同环境log级别 如: app.config['LOGGER_LEVEL']

# Set log storage location

info_log = os.path.join(app.root_path, "..", "logs", "app-info.log")

info_file_handler = logging.handlers.RotatingFileHandler(

info_log, maxBytes=1048576, backupCount=20)

# handers Level > logger Level ,might be overwrite

info_file_handler.setLevel(logging.INFO) # 可以设置不同环境log级别 如: app.config['HANDLER_LEVEL']

# set log format

info_file_handler.setFormatter(logging.Formatter(

'%(asctime)s %(levelname)s: %(message)s '

'[in %(pathname)s:%(lineno)d]')

)

app.logger.addHandler(info_file_handler)

ADMINS = ['4xxxxxx@qq.com']

mail_handler = SMTPHandler(app.config['MAIL_SERVER'],

app.config['MAIL_USERNAME'],

ADMINS,

'O_ops... %s failed!' % app.config['PROJECT'],

(app.config['MAIL_USERNAME'],

app.config['MAIL_PASSWORD']))

mail_handler.setLevel(logging.ERROR)

mail_handler.setFormatter(logging.Formatter(

'%(asctime)s %(levelname)s: %(message)s '

'[in %(pathname)s:%(lineno)d]')

)

app.logger.addHandler(mail_handler)

伟大的项目 全局使用log

current_app.logger.debug("debug信息")

current_app.logger.warning("warning信息")

current_app.logger.info("info信息")

current_app.logger.error("error信息")

current_app.logger.critical("critical信息")

四、zipfile

1 模块介绍

zipfile模块提供了创建、读取、写入、追加和列出zip文件的工具, 官网链接:https://docs.python.org/3/library/zipfile.html

2 简单示例

2.1 目录:

2.2 压缩:

def zip_write(zip_dir, zipname):

"""

压缩文件

:param zip_dir:压缩路径

:param zipname:压缩后名称

:return:

"""

with zipfile.ZipFile(zipname, "w", zipfile.ZIP_DEFLATED) as zf:

for path, dirnames, filenames in os.walk(zip_dir):

for filename in filenames:

zf.write(os.path.join(path, filename))

zip_write(r'C:\Users\keking\Desktop\test', 'test.zip')

2.3 压缩结果:

2.4 解压:

def zip_extract(zipname, ex_to=None):

"""

解压zip文件

:param zipname:解压文件名称

:param ex_to:解压存放路径

:return:

"""

with zipfile.ZipFile(zipname, "r") as zf:

for file in zf.namelist():

zf.extract(file, ex_to)

zip_extract(r'C:\Users\keking\Desktop\test\test.zip')

3 常用方法总结

file_dir = 'C:\Users\keking\Desktop\test\test.zip'

zip_obj = zipfile.ZipFile(file_dir)

# 获取zip文档内所有文件的信息,返回一个zipfile.ZipInfo的列表

print(zip_obj.infolist())

# 获取zip文档内所有文件的名称列表

print(zip_obj.namelist())

# 将zip文档内的信息打印到控制台上

print(zip_obj.printdir())

# 上下文管理

with zipfile.ZipFile(file_dir) as zf:

# 压缩

zip_obj.write(filename, arcname=None, compress_type=None, compresslevel=None)

filename -> 文件名称

arcname -> 存档名称,存放目录名称

compress_type -> 通过数字指定压缩方法,ZIP_STORED=0,ZIP_DEFLATED=8,ZIP_BZIP2=12,ZIP_LZMA=14

compresslevel -> 文件写入归档文件时使用的压缩级别

# 解压

zip_obj.extract(member, path=None, pwd=None)

member -> namelist()返回的子成员

path -> 解压文件提取到

pwd -> 加密文件密码

# 多级目录解压

zip_obj.extractall(path=None, members=None, pwd=None)

# 加密

zip_obj.setpassword(pwd)

4 实战应用

4.1 下载zip文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值