将字符串从配置文件转换为导入路径

时间:2019-11-06 20:35:15

标签: python python-3.x logging

我在这里有一个配置文件:

log:
  filename: 'log'
  format: '%(levelname)s:%(message)s'
  level: 'logging.INFO'

我尝试在此处的日志记录配置中使用它:

logging.basicConfig(
    filename=str(config['log']['filename']),
    format=str(config['log']['format']),
    level=str(config['log']['level'])
)

但是,大概是因为我传入了一个字符串,所以出现了此错误,但是日志记录级别需要在日志记录模块中找到一个路径。

ValueError: Unknown level: 'logging.INFO'

如何将其转换为模块路径,或者应该使用其他方法?

2 个答案:

答案 0 :(得分:0)

快速而变通的方式:

您可以使用eval()。它以字符串形式执行python代码。 (Docs

示例:

import logging

logging.basicConfig(
    level=eval('logging.INFO')
)

logging.info('Works!')

输出:

INFO:root:Works!

尽管这可行,但使用eval被认为是不好的做法,因为您可以执行任何Python代码,因此并不安全,即可以在config中传递任何内容,并且它将在您的应用程序中执行。更多信息here


更安全的方法:

在配置文件中,您可以传递“您的”定义级别的关键字,例如infowarning等(All levels

示例配置:

log:
  filename: 'log'
  format: '%(levelname)s:%(message)s'
  level: 'info'

在代码中,您可以在这些单词和实际日志记录级别之间创建映射,然后使用该实例化记录器。

import logging

#Create mappings
level_mapping = {'info': logging.INFO, 'warning': logging.WARNING}

#Read your config file
config = {} 

#When passed logging level doesn't exist in mappings, raise an exception
if config['log']['level'] not in level_mapping:
    raise ValueError('Invalid logging level passed in config!!!')

#Instantiate
logging.basicConfig(
    level=level_mapping[config['log']['level']]
)

通过这种方式,您可以将应用程序中的接受级别列入白名单。

答案 1 :(得分:0)

您可以使用logging.getLevelName('INFO')从字符串转换为日志级别(整数代码)。因此,只要您可以将配置文件更改为:

log:
  filename: 'log'
  format: '%(levelname)s:%(message)s'
  level: 'INFO'

这应该有效

logging.basicConfig(
    filename=str(config['log']['filename']),
    format=str(config['log']['format']),
    level=logging.getLevelName(config['log']['level'])
)

PS是否需要str()强制转换?