减少用于记录的样板

时间:2017-01-19 10:53:35

标签: python logging structlog

我阅读了structlog的文档:Configuration

  

目标是将每个文件的日志记录样板减少到:

from structlog import get_logger
logger = get_logger()

有没有办法甚至可以将其减少到一个导入行(没有;)?

3 个答案:

答案 0 :(得分:5)

无法在import语句中执行调用。

来自Python's grammar

import_stmt: import_name | import_from
import_name: 'import' dotted_as_names
import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
              'import' ('*' | '(' import_as_names ')' | import_as_names))
import_as_name: NAME ['as' NAME]
dotted_as_name: dotted_name ['as' NAME]
import_as_names: import_as_name (',' import_as_name)* [',']
dotted_as_names: dotted_as_name (',' dotted_as_name)*
dotted_name: NAME ('.' NAME)*

语法没有为可以调用的import语句指定表单。特别是,接受括号的唯一形式是'(' import_as_names ')',其中import_as_names定义为NAME ['as' NAME],而对函数的调用则需要使用parameters

我建议仔细阅读语法规范,以便深入理解。

但是,可以在一行中完成您的目标。以下是三种解决方案。

第一个是你在问题中提到的。第二个是由Chris_Rands在评论中引用的(稍后在an answer中)。第三个基本上是作弊,看起来像主文件中的单行。

使用分号

from structlog import get_logger; logger = get_logger()

通过调用基础__import__函数

logger = __import__('structlog').get_logger()

请注意,这是一个import语句,因为它与上述摘要的任何指定形式都不匹配。

使用中间文件

interface.py

from structlog import get_logger
logger = get_logger()

main.py

from interface import logger

这更像是作弊,但从主文件的角度来看,导入是一行。

如果您选择此方法,我强烈建议您为interface.py创建一个新文件。您可能想在logger = get_logger()的末尾添加structlog.py,但是您可以打破模块,最明显的情况是某个名为logger的变量已经存在。

这就是说,让你的代码分为两行是完全没问题的。我知道人们可以尽可能多地制作单行,因为Python非常擅长(我不会链接关于lambda表达式的帖子,但你可以很容易地找到一些例子)。

但是,get_logger实际上被引用为structlog.get_logger(*args, **kwargs),这意味着它可以接收参数来初始化它返回的记录器。 get_logger's source中记录了这些的使用方式。

现在,假设您必须执行一些处理来生成这些参数。您的代码将类似于:

from structlog import get_logger

args = initialize_args()
kwargs = initialize_kwargs()

logger = get_logger(args, kwargs)

嗯,你仍然可以把它变成一个单行......但它会变得不必要地长,而且几乎不可读。

答案 1 :(得分:5)

正如我在评论中提到的,要获得一个班轮,您可以使用Exception in template helper: TypeError: Cannot read property 'getPrinters' of undefined

__import__()

但是,正如documentation中所述,通常不建议使用logger = __import__('structlog').get_logger()

  

直接使用__import__()也是   气馁赞成importlib.import_module()

__import__()需要导入自己,并通过importlib.import_module()添加另一行,除非您通过import importlib导入importlib,这似乎是一个坏主意。

无论如何,在您的情况下,您不需要__import__()__import__(),这通常在从将模块名称存储为字符串的变量动态导入时使用。我认为你应该保留你所拥有的两条线,我认为这条线简洁易读。

答案 2 :(得分:1)

正如其他人所说,没有干净的方法可以在同一行上进行导入和函数调用。但是,这个问题可能有不同的方法。

我假设您要执行DRY原则。如果是这种情况,您可以在代码库中放置小文件:

# mylog.py
from structlog import get_logger
logger = get_logger() # or any other logic to get a compatible logger

现在,在所有其他地方,您可以直接获取logger实例:

from mylog import logger