临时python环境变量设置--PYTHONPATH,避免不同项目无法导入包的问题;日志编写和颜色变换nb_log

PYTHONPATH

项目地址

1.什么是永久性环境变量
永久性环境变量就是你在win上,点电脑右键 高级里面设置环境变量
2.什么是临时会话环境变量
临时会话环境变量,只会影响你当前单开的cmd 或者 shell窗口,不会影响到其他会话窗口

无论是单个项目还是多个项目,在调用某一个库或者包时,总会遇到需要导入另一个文件的包或者库(这个库或者包可能是别的项目的一个模块或者自己编写的模块)

正常情况下,我们设置了永久性环境变量,导入库时默认从原始配置的环境变量找对应的库

当我们需要导入本项目中修改之后的库而不是原始环境变量里的库,我们就需要配置当前项目根目录作为临时的环境变量,优先导入本项目里的库,如果找不到再默认从原始环境变量里寻找对应的库
3.运行任何python项目设置 PYTHONPATH为当前项目根目录 是个好习惯,4个好处如下

1、设置后,任意项目目录下的任意深层级文件夹下的多个脚本都可以轻松作为python运行起点
2、绝对不需要low操作硬编码 sys.path.insert
3、使用从项目根目录往下寻找模块,用绝对导入,写的脚本位置可以四处移动,代码非常牢固,可靠性高
4、与pycahrm的运行行为保持了一致,大大避免了命令行调试和pycahrm运行需要单独分别调试

如果你使用的是pycahrm,里面有设置不同文件为根目录的菜单,也可以连接到其它项目库的菜单,项目地址里有讲解

如果使用的是vs code,可以在终端或者命令行运行命令

4.如何设置临时环境变量
首先cd 到项目根目录,
如果是win上是 set PYTHONPATH=./ & python xx.py
当然可以不先cd到项目根目录,那就 set PYTHONPATH=项目根目录的绝对路径 就行了。

5.一个临时环境变量可以设置多个值
两个环境变量set PYTHONPATH=/codes/proj1;/codes/proj2

当 import 库 时候,首先从/codes/proj1 下找包或模块,如果没有再从 /codes/proj2 中查找,如果还没找到就从python的三方包site_packegs目录找,还是找不到就会报错模块不存在

所以你可以设置 PYTHONPATH为当前项目根目录和另一个公司的通用公共库项目

nb_log

项目地址

在了解nb_log炫彩日志之前先了解下log日志的基本用法

log日志语法以及代码案例

为了方便分辨不同类型日志,可以通过将不同颜色表示不同类型的日志,只需要在python环境中安装nb_log包

pip install nb_log

nb_log除了可以让日志具有炫彩的效果也有一些优势。例如

1.项目所有地方的print自动现型并在控制台可点击每行前面的链接可以精确跳转到print的地方,方便查找源码print打印的位置
在这里插入图片描述
2.使用的是python的内置logging封装的,返回的logger对象的类型是py官方内置日志的Logger类型,兼容性强

3.内置了一键入参,每个参数是独立开关,可以把日志同时记录到8个常用的地方的任意几种组合,包括 控制台 文件 钉钉 邮件 mongo kafka es 等等

4.日志命名空间独立,采用了多实例logger,按日志命名空间区分

5.对内置looging包打了猴子补丁,使日志永远不会使用同种handler重复记录

6.支持日志自定义,运行此包后,会自动在你的python项目根目录中生成nb_log_config.py文件,按说明修改

nb_log_config.py文件的修改方法

屏幕流日志效果图,设置不使用背景色块

在项目根目录下自动生成的nb_log_config.py配置文件中设置DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = False

屏幕流日志效果图,设置既不使用背景色块也不使用彩色文字

在项目根目录下自动生成的nb_log_config.py配置文件中设置 DEFAULUT_USE_COLOR_HANDLER = False

不提示设置pycharm颜色信息

如果不希望每次启动代码显示教你怎么设置pycharm颜色,可以设置 SHOW_PYCHARM_COLOR_SETINGS = False

如果想改变日志模板

可以设置 FORMATTER_KIND 参数,只带了7种模板,可以自定义添加喜欢的模板

日志显示方式(控制台,文件)

控制台日志

from nb_log import LogManager,get_logger

# logger = LogManager('lalala').get_logger_and_add_handlers()
logger = get_logger('lalala') # 这个和上面的效果一样,但上面的LogManager还有其他公有方法可以使用。

logger.debug('绿色')
logger.info('蓝色')
logger.warn('黄色')
logger.error('紫红色')
logger.critical('血红色')
print('print样式被自动发生变化')

文件日志

指定log_filename不为None 就自动写入文件了,并且默认使用的是多进程安全的切割方式的filehandler。

logger = get_logger('lalala',log_filename='ha.log')

默认都添加了控制台日志,如果不想要控制台日志,设置is_add_stream_handler=False

LogManager类的get_logger_and_add_handlers()函数与get_logger函数参数解析

LogManager是一个日志管理类,用于创建logger和添加handler,支持将日志打印到控制台打印和写入日志文件和mongodb和邮件

def get_logger_and_add_handlers(self, log_level_int: int = None, *, is_add_stream_handler=True,
                                    do_not_use_color_handler=None, log_path=None,
                                    log_filename=None, log_file_size: int = None,
                                    log_file_handler_type: int = None,
                                    mongo_url=None, is_add_elastic_handler=False, is_add_kafka_handler=False,
                                    ding_talk_token=None, ding_talk_time_interval=60,
                                    mail_handler_config: MailHandlerConfig = MailHandlerConfig(),
                                    is_add_mail_handler=False,
                                    formatter_template: typing.Union[int, logging.Formatter] = None):
        """
       :param log_level_int: 日志输出级别,设置为 1 2 3 4 5,分别对应原生logging.DEBUG(10),logging.INFO(20),logging.WARNING(30),logging.ERROR(40),logging.CRITICAL(50)级别,现在可以直接用10 20 30 40 50了,兼容了。
       :param is_add_stream_handler: 是否打印日志到控制台
       :param do_not_use_color_handler :是否禁止使用color彩色日志
       :param log_path: 设置存放日志的文件夹路径,如果不设置,则取nb_log_config.LOG_PATH,如果配置中也没指定则自动在代码所在磁盘的根目录创建/pythonlogs文件夹,
              非windwos下要注意账号权限问题(如果python没权限在根目录建/pythonlogs,则需要手动先创建好)
       :param log_filename: 日志的名字,仅当log_path和log_filename都不为None时候才写入到日志文件。
       :param log_file_size :日志大小,单位M,默认100M
       :param log_file_handler_type :这个值可以设置为1 2 3 4 四种值,1为使用多进程安全按日志文件大小切割的文件日志
              2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个日志
              3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
              4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
              5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
                这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
       :param mongo_url : mongodb的连接,为None时候不添加mongohandler
       :param is_add_elastic_handler: 是否记录到es中。
       :param is_add_kafka_handler: 日志是否发布到kafka。
       :param ding_talk_token:钉钉机器人token
       :param ding_talk_time_interval : 时间间隔,少于这个时间不发送钉钉消息
       :param mail_handler_config : 邮件配置
       :param is_add_mail_handler :是否发邮件
       :param formatter_template :日志模板,如果为数字,则为nb_log_config.py字典formatter_dict的键对应的模板,
                                1为formatter_dict的详细模板,2为简要模板,5为最好模板。
                                如果为logging.Formatter对象,则直接使用用户传入的模板。
       :type log_level_int :int
       :type is_add_stream_handler :bool
       :type log_path :str
       :type log_filename :str
       :type mongo_url :str
       :type log_file_size :int
       """
        if log_level_int is None:
            log_level_int = nb_log_config_default.LOG_LEVEL_FILTER
        if do_not_use_color_handler is None:
            do_not_use_color_handler = not nb_log_config_default.DEFAULUT_USE_COLOR_HANDLER
        if log_filename is None and nb_log_config_default.DEFAULT_ADD_MULTIPROCESSING_SAFE_ROATING_FILE_HANDLER:
            log_filename = f'{self._logger_name}.log'
        if log_file_size is None:
            log_file_size = nb_log_config_default.LOG_FILE_SIZE
        if log_path is None:
            # print(nb_log_config_default.LOG_PATH)
            log_path = nb_log_config_default.LOG_PATH or '/pythonlogs'
        if formatter_template is None:
            formatter_template = nb_log_config_default.FORMATTER_KIND

        self._logger_level = log_level_int * 10 if log_level_int < 10 else log_level_int
        if self._logger_name in self.preset_name__level_map:
            # print(self.preset_name__level_map)
            self._logger_level2 = (self.preset_name__level_map[self._logger_name])
        else:
            self._logger_level2 = self._logger_level
        self._is_add_stream_handler = is_add_stream_handler
        self._do_not_use_color_handler = do_not_use_color_handler
        self._log_path = log_path
        self._log_filename = log_filename
        self._log_file_size = log_file_size
        if log_file_handler_type not in (None, 1, 2, 3, 4, 5):
            raise ValueError("log_file_handler_type的值必须设置为 1 2 3 4这四个数字")
        self._log_file_handler_type = log_file_handler_type or nb_log_config_default.LOG_FILE_HANDLER_TYPE
        self._mongo_url = mongo_url
        self._is_add_elastic_handler = is_add_elastic_handler
        self._is_add_kafka_handler = is_add_kafka_handler
        self._ding_talk_token = ding_talk_token
        self._ding_talk_time_interval = ding_talk_time_interval
        self._mail_handler_config = mail_handler_config
        self._is_add_mail_handler = is_add_mail_handler

        if isinstance(formatter_template, int):
            self._formatter = nb_log_config_default.FORMATTER_DICT[formatter_template]
        elif isinstance(formatter_template, logging.Formatter):
            self._formatter = formatter_template
        else:
            raise ValueError('设置的 formatter_template 不正确')

        self.logger.setLevel(self._logger_level2)
        self.__add_handlers()
        # self.logger_name_list.append(self._logger_name)
        # self.logger_list.append(self.logger)
        return self.logger
def get_logger(name: typing.Union[str, None], *, log_level_int: int = None, is_add_stream_handler=True,
               do_not_use_color_handler=None, log_path=None,
               log_filename=None, log_file_size: int = None,
               log_file_handler_type: int = None,
               mongo_url=None, is_add_elastic_handler=False, is_add_kafka_handler=False,
               ding_talk_token=None, ding_talk_time_interval=60,
               mail_handler_config: MailHandlerConfig = MailHandlerConfig(), is_add_mail_handler=False,
               formatter_template: int = None) -> logging.Logger:
    """
    重写一遍,是为了更好的pycharm自动补全,所以不用**kwargs的写法。
    如果太喜欢函数调用了,可以使用这种.
    get_logger_and_add_handlers是LogManager类最常用的公有方法,其他方法使用场景的频率比较低,
    但如果要使用那些低频率功能,还是要亲自调用LogManger类,而不是仅仅只了解此函数的用法。
       :param name: 日志命名空间,重要。
       :param log_level_int: 日志输出级别,设置为 1 2 3 4 5,分别对应原生logging.DEBUG(10),logging.INFO(20),
       logging.WARNING(30),logging.ERROR(40),logging.CRITICAL(50)级别,现在可以直接用10 20 30 40 50了,兼容了。

       :param is_add_stream_handler: 是否打印日志到控制台
       :param do_not_use_color_handler :是否禁止使用color彩色日志
       :param log_path: 设置存放日志的文件夹路径,如果不设置,则取nb_log_config.LOG_PATH,如果配置中也没指定则自动在代码所在磁盘的根目录创建/pythonlogs文件夹,
              非windwos下要注意账号权限问题(如果python没权限在根目录建/pythonlogs,则需要手动先创建好)
       :param log_filename: 日志的名字,仅当log_path和log_filename都不为None时候才写入到日志文件。
       :param log_file_size :日志大小,单位M,默认100M
       :param log_file_handler_type :这个值可以设置为1 2 3 4 四种值,1为使用多进程安全按日志文件大小切割的文件日志,
              2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个日志
              3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
              4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
              5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
                这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
       :param mongo_url : mongodb的连接,为None时候不添加mongohandler
       :param is_add_elastic_handler: 是否记录到es中。
       :param is_add_kafka_handler: 日志是否发布到kafka。
       :param ding_talk_token:钉钉机器人token
       :param ding_talk_time_interval : 时间间隔,少于这个时间不发送钉钉消息
       :param mail_handler_config : 邮件配置
       :param is_add_mail_handler :是否发邮件
        :param formatter_template :日志模板,如果为数字,则为nb_log_config.py字典formatter_dict的键对应的模板,
                                1为formatter_dict的详细模板,2为简要模板,5为最好模板。
                                如果为logging.Formatter对象,则直接使用用户传入的模板。
       :type log_level_int :int
       :type is_add_stream_handler :bool
       :type log_path :str
       :type log_filename :str
       :type mongo_url :str
       :type log_file_size :int
    """
    locals_copy = copy.copy(locals())
    locals_copy.pop('name')
    # print(locals_copy)
    return LogManager(name).get_logger_and_add_handlers(**locals_copy)

可以看出两个函数的参数基本一样,用法一致。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值