Я очень плохо знаком с Python и многопоточным программированием в целом. В основном у меня есть сценарий, который скопирует файлы в другое местоположение. Я хотел бы, чтобы это было помещено в другой поток, таким образом, я могу произвести ....
указать, что сценарий все еще работает.
Проблема, которую я имею, состоит в том, что, если файлы не могут быть скопированы, это выдаст исключение. Это в порядке при выполнении в основном потоке; однако, наличие следующего кода не работает:
try:
threadClass = TheThread(param1, param2, etc.)
threadClass.start() ##### **Exception takes place here**
except:
print "Caught an exception"
В самом классе потока я пытался повторно бросить исключение, но это не работает. Я видел, что люди на здесь задают подобные вопросы, но они все, кажется, делают что-то более определенное, чем, что я пытаюсь сделать (и я не вполне понимаю предлагаемых решений). Я видел, что люди упоминают использование sys.exc_info()
, однако я не знаю, где или как использовать его.
Вся справка значительно ценится!
Править: Код для класса потока ниже:
class TheThread(threading.Thread):
def __init__(self, sourceFolder, destFolder):
threading.Thread.__init__(self)
self.sourceFolder = sourceFolder
self.destFolder = destFolder
def run(self):
try:
shul.copytree(self.sourceFolder, self.destFolder)
except:
raise
Проблема в том, что thread_obj.start ()
возвращается немедленно. Дочерний поток, который вы создали, выполняется в собственном контексте со своим собственным стеком. Любое возникающее исключение существует в контексте дочернего потока и находится в его собственном стеке. Один из способов, который я могу придумать прямо сейчас, передать эту информацию родительскому потоку, - это использовать какой-то тип передачи сообщений, так что вы можете изучить это.
Примерьте это на размер:
import sys
import threading
import Queue
class ExcThread(threading.Thread):
def __init__(self, bucket):
threading.Thread.__init__(self)
self.bucket = bucket
def run(self):
try:
raise Exception('An error occured here.')
except Exception:
self.bucket.put(sys.exc_info())
def main():
bucket = Queue.Queue()
thread_obj = ExcThread(bucket)
thread_obj.start()
while True:
try:
exc = bucket.get(block=False)
except Queue.Empty:
pass
else:
exc_type, exc_obj, exc_trace = exc
# deal with the exception
print exc_type, exc_obj
print exc_trace
thread_obj.join(0.1)
if thread_obj.isAlive():
continue
else:
break
if __name__ == '__main__':
main()
Использование открытых исключений - не лучшая практика, потому что обычно вы ловите больше, чем рассчитываете.
Я бы предложил изменить за исключением
, чтобы перехватить ТОЛЬКО исключение, которое вы хотите обработать. Я не думаю, что его повышение имеет желаемый эффект, потому что, когда вы переходите к созданию экземпляра TheThread
во внешнем , попробуйте
, если оно вызывает исключение, присвоение никогда не произойдет. .
Вместо этого вы можете просто предупредить об этом и двигаться дальше, например:
def run(self):
try:
shul.copytree(self.sourceFolder, self.destFolder)
except OSError, err:
print err
Затем, когда это исключение будет обнаружено, вы можете обработать его там. Затем, когда внешний try
перехватывает исключение из TheThread
, вы знаете, что это не будет тот, который вы уже обработали, и поможет вам изолировать поток вашего процесса.