9

xlrd用来处理 Excel 文件。我正在包含许多文件的文件夹上运行脚本,并且正在打印与文件相关的消息。但是,对于我运行的每个文件,我也会收到以下 xlrd 生成的错误消息:

WARNING *** OLE2 inconsistency: SSCS size is 0 but SSAT size is non-zero

有没有办法抑制这个错误消息,所以 CLI 只会打印我想要的消息?

4

5 回答 5

12

查看xlrd 文档的相关部分。该open_workbook函数的第二个参数logfile应该是一个打开的文件对象或类似行为。它需要支持的只是一种write方法。它默认为sys.stdout.

所以,像这样(未经测试)的东西应该可以完成这项工作:

class MyFilter(object):
    def __init__(self, mylogfile=sys.stdout):
        self.f = mylogfile
    def write(self, data):
        if "WARNING *** OLE2 inconsistency" not in data:
            self.f.write(data)

#start up
log = open("the_log_file.txt", "w")
log_filter = MyFilter(log)
book = xlrd.open_workbook("foo.xls", logfile=log_filter)

# shut down
log.close()
# or use a "with" statement

更新以响应@DaniloBargen 的回答:

这不是xlrd单独编写换行符,而是 Pythonprint语句/函数。这个脚本:

class FakeFile(object):
    def write(self, data):
        print repr(data)

ff = FakeFile()
for x in "foo bar baz".split():
    print >> ff, x

为所有 Python 2.2 到 2.7 产生这个输出:

'foo'
'\n'
'bar'
'\n'
'baz'
'\n'

适当现代化的脚本(打印为函数而不是语句)为 2.6、2.7、3.1、3.2 和 3.3 生成相同的输出。您可以使用更复杂的过滤器类来解决此问题。以下示例还允许检查一系列短语:

import sys, glob, xlrd

class MyFilter(object):
    def __init__(self, mylogfile=sys.stdout, skip_list=()):
        self.f = mylogfile
        self.state = 0
        self.skip_list = skip_list
    def write(self, data):
        if self.state == 0:
            found = any(x in data for x in self.skip_list)
            if not found:
                self.f.write(data)
                return
            if data[-1] != '\n':
                self.state = 1
        else:
            if data != '\n':
                self.f.write(data)
            self.state = 0

logf = open("the_log_file.txt", "w")
skip_these = (
    "WARNING *** OLE2 inconsistency",
    )
try:        
    log_filter = MyFilter(logf, skip_these)
    for fname in glob.glob(sys.argv[1]):
        logf.write("=== %s ===\n" % fname)
        book = xlrd.open_workbook(fname, logfile=log_filter)
finally:
    logf.close()
于 2011-10-01T11:54:00.227 回答
12

约翰的回答有效,但有一个小问题:

xlrd 将该警告消息和以下换行符分别写入日志文件。因此,如果您使用 John 提出的过滤器类,您将在标准输出中得到一个空行而不是消息。但是,您也不应该简单地从日志输出中过滤掉所有换行符,因为可能会有“真实的”警告会丢失换行符。

如果您想简单地忽略 xlrd 的所有日志输出,这可能是最简单的解决方案:

book = xlrd.open_workbook("foo.xls", logfile=open(os.devnull, 'w'))
于 2013-03-09T19:52:46.660 回答
0
import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    fxn()

-> http://docs.python.org/library/warnings.html#temporarily-suppressing-warnings

于 2011-10-01T09:23:07.853 回答
0

对于它的价值,我得到了同样的警告信息;当我删除第一行(为空的)时,警告消失了。

于 2015-10-28T18:16:38.453 回答
0

根据John Machin 的回答,这里有一些工作代码(使用 Python 3.6 测试),适用于sys.stdout

import io
import sys
import xlrd

path = "somefile.xls" # path to an XLS file to load or a file-like object for one
encoding_override = None

# Mute xlrd warnings for OLE inconsistencies
class LogFilter(io.TextIOWrapper):
    def __init__(self, buffer=sys.stdout, *args, **kwargs):
        self.buffer = buffer
        super(LogFilter, self).__init__(buffer, *args, **kwargs)
    def write(self, data):
        if isinstance(data, str):
            if not data.startswith("WARNING *** OLE2 inconsistency: "):
                super(LogFilter, self).write(data)
        elif isinstance(data, bytes):
            super(LogFilter, self).write(data.decode(self.buffer.encoding))
        else:
            super(LogFilter, self).write(data)

def open_workbook(file_contents, encoding_override):
    logfilter = LogFilter()
    return xlrd.open_workbook(file_contents=file_contents, logfile=logfilter,
                              encoding_override=encoding_override)

if hasattr(path, 'read'):
    book = open_workbook(file_contents=path.read(), encoding_override=encoding_override)
else:
    with open(path, 'rb') as f:
        book = open_workbook(file_contents=f.read(), encoding_override=encoding_override)
于 2019-11-14T21:21:03.257 回答