Как сделать неблокирующий выбор URL в Python

Я пишу графическое приложение в Pyglet , которое должно отображать десятки и сотни эскизов из Интернета. Прямо сейчас, я использую urllib.urlretrieve, чтобы схватить их, но это блокируется каждый раз, пока они не закончатся, и только захватывает по одному.

Я бы предпочел загружать их параллельно и иметь каждый из них, как только он будет завершен, без блокировки GUI в любой точке. Каков наилучший способ сделать это?

Я не знаю много о потоках, но похоже, что это может помочь в потоковом модуле? Или, может быть, есть какой-то простой способ, который я забыл.

  • Как преобразовать RGB в CMYK и наоборот в python?
  • Поиск индекса списка в цикле
  • получить список всех маршрутов, определенных в приложении
  • Импорт / контекст флажка-SQLAlchemy
  • Проблема округления на Python
  • Тестирование кода, для которого требуется приложение Flask или контекст запроса
  • Получение максимальной амплитуды для аудиофайла в секунду
  • пробуя все комбинации операций над списком переменных
  • 6 Solutions collect form web for “Как сделать неблокирующий выбор URL в Python”

    Вероятно, вам multiprocessing модули threading или multiprocessing . На самом деле вам не нужно создавать все эти классы на основе Thread , есть более простой метод с использованием Pool.map :

     from multiprocessing import Pool def fetch_url(url): # Fetch the URL contents and save it anywhere you need and # return something meaningful (like filename or error code), # if you wish. ... pool = Pool(processes=4) result = pool.map(f, image_url_list) 

    Как вы подозревали, это идеальная ситуация для нарезки. Вот краткий путеводитель, который я нашел очень полезным, когда делал свой собственный первый бит потоковой передачи в python.

    Как вы правильно указали, вы можете создать несколько потоков, каждый из которых отвечает за выполнение операций urlretrieve. Это позволяет непрерывной работе основного потока.

    Вот учебник по потоковому использованию в python: http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf

    Вот пример использования threading.Thread. Просто замените имя класса своей собственной и функцией запуска на свой собственный. Обратите внимание, что многопоточность отлично подходит для приложений с ограниченным доступом, таких как ваши, и может действительно ускорить их. Использование pythong threading строго для вычисления в стандартном python не помогает, потому что только один поток может вычислять за раз.

     import threading, time class Ping(threading.Thread): def __init__(self, multiple): threading.Thread.__init__(self) self.multiple = multiple def run(self): #sleeps 3 seconds then prints 'pong' x times time.sleep(3) printString = 'pong' * self.multiple pingInstance = Ping(3) pingInstance.start() #your run function will be called with the start function print "pingInstance is alive? : %d" % pingInstance.isAlive() #will return True, or 1 print "Number of threads alive: %d" % threading.activeCount() #main thread + class instance time.sleep(3.5) print "Number of threads alive: %d" % threading.activeCount() print "pingInstance is alive?: %d" % pingInstance.isAlive() #isAlive returns false when your thread reaches the end of it's run function. #only main thread now 

    У вас есть выбор:

    • Темы: простейший, но недостаточно масштабируемый
    • Twisted: средняя сложность, хорошо масштабируется, но имеет общий объем процессора из-за GIL и однопоточный.
    • Многопроцессорность: сложнее. Хорошо масштабируется, если вы знаете, как написать собственный цикл событий.

    Я рекомендую использовать только потоки, если вам не нужен промышленный выборщик.

    Вам либо нужно использовать потоки, либо асинхронную сетевую библиотеку, такую ​​как Twisted . Я подозреваю, что использование потоков может быть проще в вашем конкретном случае использования.

    Interesting Posts
    Python - лучший язык программирования в мире.