Вместо того, чтобы ждать завершения потока, вы можете вместо этого отправить отладочный вывод в какой-то буфер, а затем организовать IPython для печати содержимого этого буфера каждый раз, когда он печатает приглашение.Чтобы увидеть больше результатов отладки, вы вводите пустую строку, чтобы заставить IPython сбросить буфер в консоль:
def ipython_logging():
import logging.handlers
# setup a logging handler to actually print output to the console
console = logging.StreamHandler()
console.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
console.setLevel(logging.DEBUG)
# then setup a handler that buffers the output. the float('inf')'s suppress automatic flushing.
memory = logging.handlers.MemoryHandler(capacity=float('inf'),
flushLevel=float('inf'),
target=console)
memory.setLevel(logging.DEBUG)
logging.root.addHandler(memory)
logging.root.setLevel(logging.DEBUG)
# tell IPython to flush the buffer every time it prints a prompt.
import IPython
def flush_log(self, *args, **kwargs):
memory.flush()
raise IPython.ipapi.TryNext
ip = IPython.ipapi.get()
ip.set_hook("generate_prompt", flush_log)
Таким образом, вы можете сделать запись из вашего потока:
import logging
import threading
import time
import random
LOGGER = logging.getLogger(__name__)
class MyThread(threading.Thread):
def __init__(self, threadnum):
super(MyThread, self).__init__()
self.__threadnum = threadnum
def run(self):
freq = random.randrange(1,10)
count = random.randrange(20)
for i in range(count):
time.sleep(freq)
LOGGER.debug("output from #%d, i=%d, freq=%d", self.__threadnum, i, freq)
который при использовании может выглядеть примерно так:
$ ipython
Python 2.7.1 (r271:86832, Apr 12 2011, 16:15:16)
Type "copyright", "credits" or "license" for more information.
IPython 0.10.2 -- An enhanced Interactive Python.
In [1]: import soithreads
In [2]: soithreads.ipython_logging()
In [3]: [soithreads.MyThread(n).start() for n in range(3)]
Out[3]: [None, None, None]
In [4]:
In [5]:
In [6]:
In [7]:
DEBUG:soithreads:output from #1, i=0, freq=3
In [8]:
In [9]:
DEBUG:soithreads:output from #1, i=1, freq=3
In [10]:
In [11]:
In [12]:
In [13]:
DEBUG:soithreads:output from #2, i=0, freq=8
In [14]:
In [15]:
DEBUG:soithreads:output from #1, i=2, freq=3
DEBUG:soithreads:output from #0, i=0, freq=9
In [16]:
In [17]:
DEBUG:soithreads:output from #1, i=3, freq=3
In [18]:
In [19]:
In [20]:
In [21]:
In [22]:
In [23]:
DEBUG:soithreads:output from #1, i=4, freq=3
In [24]:
In [25]:
DEBUG:soithreads:output from #2, i=1, freq=8
In [26]:
In [27]:
In [28]:
In [29]:
DEBUG:soithreads:output from #1, i=5, freq=3
DEBUG:soithreads:output from #0, i=1, freq=9
In [30]:
In [31]:
In [32]:
In [33]:
In [34]:
In [35]:
DEBUG:soithreads:output from #2, i=2, freq=8
DEBUG:soithreads:output from #0, i=2, freq=9
DEBUG:soithreads:output from #2, i=3, freq=8
DEBUG:soithreads:output from #0, i=3, freq=9
DEBUG:soithreads:output from #2, i=4, freq=8
DEBUG:soithreads:output from #0, i=4, freq=9
DEBUG:soithreads:output from #0, i=5, freq=9
DEBUG:soithreads:output from #0, i=6, freq=9
In [36]: