Как получить название анализируемого завершенного будущего в concurrent.futures? - PullRequest
0 голосов
/ 08 ноября 2019

При поиске ответа на мой вопрос (решение доступно в одном ответе в связанном дубликате), я обнаружил concurrent.futures, а именно concurrent.futures.as_completed.

Код, с которым я закончил (для контекста: мне нужно было отловить в основной программе исключения, возникшие в потоках, запущенных из этой основной программы), работает нормально, за исключением того, что я не знаю, как повторно присоединить кимя функции, которая проверяется в concurrent.futures.as_completed:

import concurrent.futures

class Checks:

    @staticmethod
    def isok():
        print("OK")

    @staticmethod
    def isko():
        raise Exception("KO")

# db will keep a map of method names in Check with the thread handler
db = {}

with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
    # get the names of the methods in Check, discarding the built-ion ones
    for check in [k for k in dir(Checks) if not k.startswith('_')]:
        db[check] = executor.submit(getattr(Checks, check))

# at that point I have a map of function_name_as_a_string -> thread handler
for future in concurrent.futures.as_completed([db[k] for k in db.keys()]):
    if future.exception():
        print(f"{str(future.exception())} was raised (I do not know where, somewhere)")
    else:
        print("success (again, I do not know where, exactly)")

# all the threads are finished at that point
print("all threads are done")

В выходных данных об успехе / неудаче я знаю, что метод вызывается или не является исключением. То, что я не знаю, это то, что кто сделал.

Поскольку итерация должна выполняться над обработчиками потоков, я не смог найти способ «вставить» имя метода в цикл, чтобы использовать его вprint() - как я могу это сделать?

1 Ответ

0 голосов
/ 08 ноября 2019

Возможное решение - использовать zip() и создать итератор кортежей (name, handler):

import concurrent.futures

class Checks:

    @staticmethod
    def isok():
        print("OK")

    @staticmethod
    def isko():
        raise Exception("KO")

# db will keep a map of method namles in Check with the actual (executable) method
db = {}

with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
    for check in [k for k in dir(Checks) if not k.startswith('_')]:
        db[check] = executor.submit(getattr(Checks, check))

for name, handler in zip(db.keys(), concurrent.futures.as_completed([db[k] for k in db.keys()])):
    if handler.exception():
        print(f"{str(handler.exception())} was raised by {name}")
    else:
        print(f"success in {name}")

# all the threads are finished at that point
print("all threads are done")
...