rdkit 是一个神奇的 python 包。它的函数主体部分是 C++ 写的,python 仅仅提供接口。具体到日志模块,rdkit python 中看不到源码,官方只是提供了一些函数接口供调用。
较常见的场景:
- slience warnings:
python">from rdkit.rdBase import DisableLog
from rdkit import Chem
DisableLog("rdApp.*")
mol = Chem.MolFromSmiles("invalid_smiles")
rdkit 有四种级别的日志信息:
'rdApp.debug', 'rdApp.info', 'rdApp.warning', 'rdApp.error'
使用 rdApp.*
可以涵盖所有 4种
静默 rdkit 的警告信息是最常见的需求,网上教程也很多。但是捕获 rdkit 的警告信息则完全没有正确答案。
- capture warnings
rdkit 的日志是 C++ 的日志,无法通过 python stdout or python stderr 进行捕获。但是仔细看rdkit.rdBase
库会发现,rdkit 提供了一个函数WrapLogs
将日志转化为python stderr
后面我们就可以通过标准的 python 输出捕获模块进行捕获:
python">from rdkit.rdBase import DisableLog, WrapLogs
from rdkit import Chem
# DisableLog("rdApp.*")
# mol = Chem.MolFromSmiles("invalid_smiles")
WrapLogs()
import contextlib, io
f = io.StringIO()
with contextlib.redirect_stderr(f):
mol = Chem.MolFromSmiles("invalid_smiles")
output = f.getvalue()
print('Captured info:')
print(output)
需要注意的是,有的 warning 没有经过 rdkit 的包装,如下:
!!! Warning !!! Distance between atoms 19 and 16 (0.977241 A) is suspicious.
这种情况可以归类为非正式 warning ,rdkit 会在这些 warning 后面加上正式的 warning 。