区分py文件的两种用途

def f1():
    print("x")

print(__name__)		# 运行文件的时候打印结果为__main__

运行文件的时候__name__等于__main__
当文件被导入使用的时候__name__等于模块名
也就是说下面的if判断下的函数运行只能被当成执行文件运行,当成模块导入是不会运行函数f1的
if __name__ == "__main__":
    f1()

使用if判断main可以使文件导入的时候只导入代码文件,不运行文件代码。只有run的时候才会运行文件

包的使用

包的文件只能被导入,不能运行
首次导入包发生的事情
import导入文件,会先执行一个_init_.py文件,申请一个包的名称空间,执行_init_.py文件,将_init_.py文件运行过程中产生的名字导入包的名称空间

运行pyd文件需要Python版本一致吗_文件路径

在当前位置拿到一个aaaa,指向该名称空间,导入包就是导入_init_.py文件。
向aaaa的文件要名字,就是向aaaa下的_init_.py文件要名字
import aaaa
print(aaaa.x)
print(aaaa.y)
aaaa.m1.f1()

import aaaa
aaaa.bbbb.m3.f3()

绝对导入与相对导入

绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入
       优点: 执行文件与被导入的模块中都可以使用
       缺点: 所有导入都是以sys.path为起始点,导入麻烦

相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入
       符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹
       优点: 导入更加简单
       缺点: 只能在导入包中的模块时才能使用

总结包的使用

导包就是在导包下的_init_.py文件
包内部的导入应该使用相对导入,相对导入也只能在包内部使用,而且...取上一级不能出包
使用语句中的点代表的是访问属性
    m.n.x---->向m要n,向n要x
而导入语句中的点代表的是路径分隔符
    import a.b.c---->a/b/c,文件夹下的a下有子文件夹b,文件夹b下有子文件或文件夹c
所以导入语句中的点的左边必须是一个包

日志模板图

运行pyd文件需要Python版本一致吗_存到文件_02

1、定义三种日志输出格式,日志中可能用到的格式化串如下

%(name)s Logger的名字
 %(levelno)s 数字形式的日志级别
 %(levelname)s 文本形式的日志级别
 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
 %(filename)s 调用日志输出函数的模块的文件名
 %(module)s 调用日志输出函数的模块名
 %(funcName)s 调用日志输出函数的函数名
 %(lineno)d 调用日志输出函数的语句所在的代码行
 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
 %(thread)d 线程ID。可能没有
 %(threadName)s 线程名。可能没有
 %(process)d 进程ID。可能没有
 %(message)s用户输出的消息

2、强调:其中的%(name)s为getlogger时指定的名字

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'

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

test_format = '%(asctime)s] %(message)s'

3、日志级别

critical => 50
     error => 40
     warning => 30
     info => 20
     debug => 10
日志级别是自下而上的,如果把级别设置成debug,那么所有的日志级别都能通过
如果日志级别设置成error的,那么只能error和critical日志级别能通过

配置日志格式

standard_format = "%(asctime)s %(filename)s:%(lineno)d %(name)s %(levelname)s %(message)s "  # 标准格式
simple_format = "%(asctime)s %(message)s"  # 简单格式
LOGGING_DIC = {
    'version': 1,  # 日志配置版本
    'disable_existing_loggers': False,  # 禁用现有的日志记录器
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        # 'test': {
        #     'format': test_format
        # },
    },  # 控制日志格式
    'filters': {},  # 过滤器
    'handlers': {
        # 打印到文件的日志,收集info及以上的日志
        # 'file1': {
        #     'level': 'DEBUG',
        #     'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
        #     'formatter': 'standard',
        #     # 可以定制日志文件路径
        #     # BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
        #     # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
        #     'filename': 'a1.log',  # 日志文件
        #     'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
        #     'backupCount': 5,
        #     'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        # },
        'file1': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': 'a1.log',  # 注意:这个是文件路径,在项目中需要换成项目中需要改的文件路径
            'encoding': 'utf-8',
        },
        'file2': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': 'a2.log',  # 注意:这个是文件路径,在项目中需要换成项目中需要改的文件路径
            'encoding': 'utf-8',
        },
        # 打印到终端的日志
        'stream': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
    },  # 控制日志输出的地方
    'loggers': {
        # logging.getLogger(__name__)拿到的logger配置
        "安全相关": {
            'handlers': ['file1', 'file2', 'stream'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'ERROR',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
        "": {
            'handlers': ['file1', 'file2', 'stream'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'CRITICAL',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
    },
}
# 设置loggers时,如果我们寻找的日志名称在loggers中,那么以找到的名称为准,如果没有找到loggers,那么会以""中的设置为准

调用模块设置

import settings
import logging.config           # 内置的子模块

def get_logger(name):
    logging.config.dictConfig(settings.LOGGING_DIC)   
    #加载配置,把settings文件中的LOGGING_DIC加载到logging.config.dictConfig中
    return logging.getLogger(name)

logger1 = get_logger("用户交易")
logger1.info("nana给了吴彦祖1个亿")
logger1.debug("调试日志")
logger1.warning("警告")
logger1.error("错误")
logger1.critical("危机")

logger1 = get_logger("安全相关")
logger1.info("常规")
logger1.debug("调试日志")
logger1.warning("警告")
logger1.error("错误")
logger1.critical("危机")