17.Python略有小成(包,logging模块)
Python(包,logging模块)
一、包
什么是包
官网解释 : 包是一种通过使用‘.模块名’来组织python模块名称空间的方式 , 具体来讲 , 包就是一个包含有__ init __.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来
- 在python3中,即使包下没有__ init __.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
- 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块
为何要使用包
包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来
随着功能越写越多,我们无法将所以功能都放到一个文件中,于是我们使用模块去组织功能,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性注意事项
- 关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
- import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__ init __.py,导入包本质就是在导入该文件
- 包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间
二、包的使用
示例文件
# 此示例摘抄他人博客,挺不错的.
glance/ #Top-level package
├── __init__.py #Initialize the glance package
├── api #Subpackage for api
│ ├── __init__.py
│ ├── policy.py
│ └── versions.py
├── cmd #Subpackage for cmd
│ ├── __init__.py
│ └── manage.py
└── db #Subpackage for db
├── __init__.py
└── models.py
文件内容
#文件内容
#policy.py
def get():
print('from policy.py')
#versions.py
def create_resource(conf):
print('from version.py: ',conf)
#manage.py
def main():
print('from manage.py')
#models.py
def register_models(engine):
print('from models.py: ',engine)
# 执行文件与示范文件在同级目录下
包的使用(import)
- import glance.db.models
- glance.db.models.register_models('mysql')
单独导入包名称时不会导入包中所有包含的所有子模块,如
#在与glance同级的test.py中
import glance
glance.cmd.manage.main()
'''
执行结果:
AttributeError: module 'glance' has no attribute 'cmd' '''
解决方法:
1 #glance/__init__.py
2 from . import cmd
3 #glance/cmd/__init__.py
4 from . import manage
执行:
1 #在于glance同级的test.py中
2 import glance
3 glance.cmd.manage.main()
包的使用(from...import...)
需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,
如:from a import b.c是错误语法
1 from glance.db import models
2 models.register_models('mysql')
3 from glance.db.models import register_models
4 register_models('mysql')
from glance.api import *
此处我们研究从一个包导入所有 *,是想从包api中导入所有,实际上该语句只会导入包api下__ init __ .py文件中定义的名字,我们可以在这个文件中定义__ all ___
#在__init__.py中定义
x=10
def func():
print('from api.__init.py')
__all__=['x','func','policy']
此时我们在于glance同级的文件中执行from glance.api import *就导入__ all __中的内容(versions仍然不能导入)。
三、绝对导入相对导入
我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:
- 绝对导入:以glance作为起始
- 相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)
例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py
1 在glance/api/version.py
2 #绝对导入
3 from glance.cmd import manage
4 manage.main()
5 #相对导入
6 from ..cmd import manage
7 manage.main()
测试结果:注意一定要在于glance同级的文件中测试
包以及包所包含的模块都是用来被导入的,而不是被直接执行的。而环境变量都是以执行文件为准的
绝对导入与相对导入总结
绝对导入与相对导入
绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入
优点: 执行文件与被导入的模块中都可以使用
缺点: 所有导入都是以sys.path为起始点,导入麻烦
相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入
符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹
优点: 导入更加简单
缺点: 只能在导入包中的模块时才能使用
注意:
1. 相对导入只能用于包内部模块之间的相互导入,导入者与被导入者都必须存在于一个包内
2. attempted relative import beyond top-level package # 试图在顶级包之外使用相对导入是错误的,言外之意,必须在顶级包内使用相对导入,每增加一个.代表跳到上一级文件夹,而上一级不应该超出顶级包
四、logging模块(日志)
工作日志分四个大类
- 系统日志 : 记录服务器的一些重要信息,如监控系统,cpu温度,网卡流量,重要的硬件的一些指标,运维人员经常使用,记录操作的一些指令
- 网站日志 : 访问异常,卡顿,网站一些板块,受欢迎程度,点击率,等等,蜘蛛爬取次数等等
- 辅助开发日志 : 开发人员在开发项目中利用日志进行排错,排除一些避免不了的错误,辅助开发.
- 记录用户信息日志 : 用户的消费习惯,新闻偏好,等等(数据库)
日志开发者使用的三个版本
简易版
# 日志应用
import logging
logging.basicConfig(level=logging.DEBUG) # 调整错误显示等级
logging.debug("debug message") # 调试模式
logging.info("info message") # 正常模式
logging.warning("warning message") # 警告信息
logging.error("error message") # 错误信息
logging.critical("critical message") # 严重错误信息
# 应用1
def func():
print("in func")
logging.debug("正常执行")
func()
# 应用2
try:
i=input("请输入选项:")
int(i)
except Exception as e:
logging.error(e)
print(11) # low版的日志缺点 : 文件与屏幕同时输入只能选择一个进行
import logging
logging.basicConfig(
level=10,
format="%(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s %(message)s",
filename=r"test.log" # 直接创建一个文件并写入
)
logging.debug("调试模式") # 10
logging.info("正常模式") # 20
logging.warning("警告信息") # 30
logging.error("错误信息") # 40
logging.critical("严重错误信息") # 50
标准版
import logging
# 创建对象
logger=logging.getLogger() # 创建一个logging对象
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) # 将配置好的文件格式和屏幕格式导入logging对象中
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
高端版(Django项目)
- 优点 : 自定制(通过字典的方式)日志
- 轮转日志的功能
# 日志旗舰版
# 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 = 'log1.log' # log文件名,当确认功能后可以更改文件名字
logfile_path=r"D:\PyCharm\python学习\day1\日志学习\旗舰版日志文件夹\log1.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第一层所有的键都不能改变
LOGGING_DIC = {
'version': 1, # 版本号
'disable_existing_loggers': False, # 固定写法
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {}, # 项目用过滤
'handlers': {
#打印到终端的日志
'sh': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'fh': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,轮转文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5, # 轮转文件设置为5个
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['sh', 'fh'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
} dic={"username":"张三丰"} def md_logger(a):
logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(a) # 生成一个log实例,()内用来区分业务
return logger def login():
md_logger("xx账户").debug(f'{dic["username"]}登录成功') login()
17.Python略有小成(包,logging模块)的更多相关文章
- Python进阶(十一)----包,logging模块
Python进阶(十一)----包,logging模块 一丶包的使用 什么是包: 包是通过使用 .模块名的方式组织python模块名称空间的方式. 通俗来说,含有一个__init__.py文件的文 ...
- Python日志输出——logging模块
Python日志输出——logging模块 标签: loggingpythonimportmodulelog4j 2012-03-06 00:18 31605人阅读 评论(8) 收藏 举报 分类: P ...
- Python中的logging模块就这么用
Python中的logging模块就这么用 1.日志日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICALDEBUG:详细的信息,通常只出现在诊断问题 ...
- Python自建logging模块
本章将介绍Python内建模块:日志模块,更多内容请从参考:Python学习指南 简单使用 最开始,我们用最短的代码体验一下logging的基本功能. import logging logger = ...
- Python实战之logging模块使用详解
用Python写代码的时候,在想看的地方写个print xx 就能在控制台上显示打印信息,这样子就能知道它是什么了,但是当我需要看大量的地方或者在一个文件中查看的时候,这时候print就不大方便了,所 ...
- 18 包 ,logging模块使用
包: 1 什么是包: 包就是一个包含有__init__.py文件的文件夹 宝本质就是一种模块,即包就是用包导入使用的,包内部包含的文件也都是用来被导入使用 2 为什么要用包 包就是文件夹,那文件加就是 ...
- Python基础-包与模块
Python基础-包与模块 写在前面 如非特别说明,下文均基于Python3 摘要 为重用以及更好的维护代码,Python使用了模块与包:一个Python文件就是一个模块,包是组织模块的特殊目录(包含 ...
- python中日志logging模块的性能及多进程详解
python中日志logging模块的性能及多进程详解 使用Python来写后台任务时,时常需要使用输出日志来记录程序运行的状态,并在发生错误时将错误的详细信息保存下来,以别调试和分析.Python的 ...
- python基础-包和模块
Python基础-包与模块 写在前面 如非特别说明,下文均基于Python3 摘要 为重用以及更好的维护代码,Python使用了模块与包:一个Python文件就是一个模块,包是组织模块的特殊目录(包含 ...
随机推荐
- learning java 实例序列化
对Person类实例进行序例化及反序例化: Person.java public class Person implements java.io.Serializable { private Stri ...
- Mscordacwks.dll/SOS.dll 调试归档
找到个好东西 为什么要归档 此存档提供帮助,并可能提供对以下问题的答案 是否可以使WinDBG在符号存储中找到mscordacwks.dll?, Windbg需要不同版本的mscordacwks.dl ...
- 【CPLEX教程03】java调用cplex求解一个TSP问题模型
00 前言 前面我们已经搭建好cplex的java环境了,相信大家已经跃跃欲试,想动手写几个模型了.今天就来拿一个TSP的问题模型来给大家演示一下吧~ CPLEX系列教程可以关注我们的公众号哦!获取更 ...
- SpringSecurity的简单入门
以下是大体思路 1.导入坐标 <properties> <spring.version>4.2.4.RELEASE</spring.version> </pr ...
- clion ctrl+鼠标左键不能调到函数实现
问题:ctrl+鼠标左键只能在函数定义和申明之间跳转,不能跳转到implement,如果按ctrl+shift+B会报“no implement”. 解决:更改CMakeList文件,更改版本号. c ...
- win10照片查看器不能看jpg等格式图片
1.首先,我们需要使用注册表编辑器来开启Win10系统照片查看器功能,因为其实这个功能是被隐藏了,那么按下Windows徽标键+R键,打开运行命令窗口,输入“regedit”命令. 2.打开注册表编辑 ...
- Linux+Tomcat环境下安装SSL证书
1.将申请好的证书(4个文件)文件放入/home/tomcat/apache-tomcat-9.0.12/conf/cert文件夹下2.(或者)将申请好的证书(4个文件)文件放入/home/tomca ...
- samba-centos7
目的: 1,匿名访问共享目录/home/home and /home/share 2,/home/samba/home 共享名为home,有读写权限,但是进入该文件夹需要验证用户 3,/home/sa ...
- ICEM-圆角正方体
原视频下载地址:https://pan.baidu.com/s/1c2cNgJm 密码: rci8
- Wireshark常用快捷键&&过滤器语法
目录 一.快捷键 二.过滤器语法 1.捕获过滤器的BPF(Berkeley Packet Filter)语法 2.显示过滤器 一.快捷键 Ctrl+M 标记/取消标记 shift+ctrl+N/B 下 ...