1

我阅读了 structlog 的文档:配置

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

from structlog import get_logger
logger = get_logger()

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

4

3 回答 3

4

不能在 import 语句中执行调用。

Python 的语法

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_as_names ')', whereimport_as_names被定义为NAME ['as' NAME],而对函数的调用需要使用parameters.

我建议彻底阅读语法规范以深入了解。


但是,可以在一行中完成您的目标。这里有三个解决方案。

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

带分号

from structlog import get_logger; logger = get_logger()

通过调用底层__import__函数

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

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

通过使用中间文件

接口.py

from structlog import get_logger
logger = get_logger()

主文件

from interface import logger

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

如果您选择这种方法,我强烈建议您为interface.py. 您可能想logger = get_logger()在 末尾添加 a 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)

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

于 2017-01-23T13:38:14.650 回答
4

正如我在评论中提到的,要获得一个衬里,您可以使用__import__()

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

但是,如文档中所述,__import__()通常不建议使用:

也不鼓励直接使用__import__()以支持importlib.import_module()

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

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

于 2017-01-23T14:45:40.427 回答
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
于 2017-01-29T18:44:21.000 回答