2011-10-01 9 views
7

Używam przetwarzania xlrd do przetwarzania plików Excel. Uruchamiam skrypt w folderze zawierającym wiele plików i drukuję wiadomości związane z plikami. Jednak dla każdego pliku biegnę, pojawia się następujący komunikat o błędzie xlrd generowane także:Python xlrd: tłumienie komunikatów ostrzegawczych

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

Czy istnieje sposób, aby stłumić ten komunikat o błędzie, więc CLI będzie drukować tylko wiadomość, którą chcesz go?

Odpowiedz

8

Zapoznaj się z odpowiedniej części xlrd docs. Drugim argumentem funkcji open_workbook jest logfile, który powinien być obiektem otwartego pliku lub podobnym do niego. Wszystko, co musi obsłużyć, to metoda write. Domyślnie jest to sys.stdout.

Tak, coś w tym rodzaju (niesprawdzone) powinien wykonać zadanie:

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 

Aktualizacja w odpowiedzi odpowiedzieć przez @DaniloBargen:

To nie xlrd że pisze o nowej linii oddzielnie, to jest to Python print Instrukcja/funkcja. Ten skrypt:

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

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

produkuje to wyjście dla wszystkich pyton 2,2 do 2,7 włącznie:

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

Odpowiednio zmodernizowany skrypt (druk w funkcji zamiast oświadczenia) wywołuje identyczną moc 2,6, 2,7 , 3.1, 3.2 i 3.3. Możesz obejść to z bardziej skomplikowaną klasą filtru. Poniższy przykład dodatkowo pozwala ciągiem wyrażeń należy sprawdzić:

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() 
+0

Dziękuję za bardziej szczegółową i szczegółową odpowiedź. Odpowiednio podjąłem twoją odpowiedź. – David542

10

Odpowiedź przez Jana działa, ale ma mały problem:

xlrd pisze, że ostrzeżenie wiadomość i dodaje znak nowej linii oddzielnie do plik dziennika. Dlatego zamiast komunikatu pojawi się pusty wiersz, jeśli użyjesz klasy filtra zaproponowanej przez Johna. Nie powinieneś po prostu odfiltrowywać wszystkich znaków nowego wiersza z wyjścia dziennika, ponieważ mogą istnieć "prawdziwe" ostrzeżenia, które nie będą zawierać nowych znaków.

Jeśli chcesz po prostu ignorować wszystkie dane wyjściowe dziennika przez xlrd, to chyba najprostsze rozwiązanie:

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

Dobry odbiór! Zobacz moją znacznie rozszerzoną odpowiedź. –

0

Na co warto miałem ten sam komunikat ostrzegawczy; kiedy usunąłem pierwszy wiersz (który był pusty) ostrzeżenie zniknęło.

Powiązane problemy