Форум сайта python.su
Хочу выловить ошибки, выходящие в окно stdout/stderr, и записывать их в error.log. Поясняю, что имею в виду ошибки не те, которые я учла с помощью except, а какие-нибудь неожиданные, например, связанные с обращением к базе данных. Наверняка есть возможность вести лог, а не показывать окно ошибок. Подскажите, пожалуйста!
Офлайн
import traceback
Офлайн
python progname.py 2&>error.log
Офлайн
wx.App навешивается на stdout/stderr и показывает окно.
wx.PySimpleApp этого не делает, при том оставаясь практически таким же по интерфейсу.
Я менял один на другой и перенаправлял вывод в файл
sys.stdout = sys.stderr = file('output.txt')
Офлайн
Андрей Светлов
wx.App тоже перенаправляет таким методом в файл, я проверила. Но получилось, что файл записывается, а программа никаких признаков ошибки не подает. Это неудобно. Может можно выводить в окно, а потом записывать в файл? или я слишком много хочу)))
Офлайн
Точно. Не знал и делал все сам.
Имеются в виду redirect=True и filename=None параметры в wx.App.__init__?
Хочешь как раз в меру :) Просто я по первому посту подумал, что нужен только лишь файл.
Как я понимаю, собственно redirect происходит в методе
def RedirectStdio(self, filename=None):
“”“Redirect sys.stdout and sys.stderr to a file or a popup window.”“”
if filename:
_sys.stdout = _sys.stderr = open(filename, ‘a’)
else:
self.stdioWin = self.outputWindowClass()
_sys.stdout = _sys.stderr = self.stdioWin
Т.е. если имя файла есть - пишем в него, если нет - пишем в outputWindowClass, который по умолчанию PyOnDemandOutputWindow, а в файл не пишем. Легко исправить. Весь вывод будет проходить через sys.stdout.write или через sys.stderr.write. И то и другое - PyOnDemandOutputWindow.
Меняем его.
import wx
import sys
class ErrorWin(wx.PyOnDemandOutputWindow):
def __init__(self, *args, **kwargs):
wx.PyOnDemandOutputWindow.__init__(self, *args, **kwargs)
self._outfile = file('output.log', ‘a’)
def write(self, msg):
wx.PyOnDemandOutputWindow.write(self, msg)
self._outfile.write(msg)
self._outfile.flush() #for forced data save
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title=“Test Frame”, size=(100, 100))
btn = wx.Button(self, -1, “Generage error”)
self.Bind(wx.EVT_BUTTON, self.onErrBtn, btn)
btn2 = wx.Button(self, -1, “Generage message”)
self.Bind(wx.EVT_BUTTON, self.onMsgBtn, btn2)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(btn)
sizer.Add(btn2)
self.SetSizer(sizer)
def onErrBtn(self, evt):
print >> sys.stderr, ‘Sample Error’
def onMsgBtn(self, evt):
print ‘Sample Message’
class App(wx.App):
outputWindowClass = ErrorWin
def OnInit(self):
frame = Frame()
self.SetTopWindow(frame)
frame.Show(True)
return True
app = App()
app.MainLoop()
Офлайн
Андрей Светлов
То, что надо, спасибо. Я до этого и не понимала, что означает redirect.
Офлайн
На здоровье.
Совет “общего плана” - читай чужие исходники. Код библиотек, которые используешь.
Очень помогает. Особенно - думать.
Тем более что практически весь Питон открытый.
И, конечно, спрашивай, если непонятно :)
Офлайн
Андрей СветловТак я и так большую часть изучаю из модулей питона. Просто иногда цепочки связей сильно запутаны или код совсем не понятен.
Совет “общего плана” - читай чужие исходники. Код библиотек, которые используешь.
Офлайн