Python xlrd: 抑制警告信息

12 投票
6 回答
19102 浏览
提问于 2025-04-17 03:28

我正在使用 xlrd 来处理 Excel 文件。我在一个包含很多文件的文件夹里运行一个脚本,并且我会打印一些与这些文件相关的信息。但是,每当我处理一个文件时,都会出现以下 xlrd 生成的错误信息:

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

有没有办法让这个错误信息不显示,这样命令行界面就只会打印我想要的信息呢?

6 个回答

1

如果你在使用pandas的read_excel函数时收到了这个警告,那么你可以这样做:

import os
import xlrd
import pandas as pd

workbook = xlrd.open_workbook(your_path, logfile=open(os.devnull, "w"))
df = pd.read_excel(workbook) # read_excel accepts workbooks too
17

John的回答是可行的,但有一个小问题:

xlrd会把警告信息和后面的换行符分开写入日志文件。所以如果你使用John提议的过滤类,你的标准输出中会出现一个空行,而不是显示警告信息。不过,你也不应该简单地把日志输出中的所有换行符都过滤掉,因为可能会有“真正的”警告信息,这样就会缺少换行符了。

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

book = xlrd.open_workbook("foo.xls", logfile=open(os.devnull, 'w'))
13

可以查看一下 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 单独写入换行符,而是 Python 的 print 语句/函数在做这件事。这个脚本:

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'

一个适当现代化的脚本(将 print 作为函数而不是语句)在 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()

撰写回答