@astrotrain

Вернуть значение из потока в python 3?

Собственно вопрос. Потоки в питоне работают шустро, но вот как нормально вернуть значение из него я не нашел. Вот пример кода:

import requests
import random
import re
import queue

pattern = 'http://www.astateoftrance.com/episodes/episode-'
k = 700
lock = threading.Lock()

def getPage():
	#print ("Hello")
	global k
	while (k < 800):
		url = pattern+str(k)+'/'
		response = requests.get(url)
		content = response.content.decode('utf-8')
		contLow = content.lower()
		#print(contLow)
		if (re.findall('', contLow)):
			print(url)
		lock.acquire()
		k = k + 1
		lock.release()

threads = []
for i in range(20):
	t = threading.Thread(target=getPage)
	threads.append(t)
	t.start()


Где-то предлагают использовать вместо threading multiprocessing, кто-то советует переопределить класс потока так чтобы он возвращал значение. Разве нет более прямого пути получить из потока значение? Или нужно обязательно использовать вспомагательное решение?
  • Вопрос задан
  • 6938 просмотров
Пригласить эксперта
Ответы на вопрос 2
@deliro
Потоки в питоне работают шустро

Это типа комплимент? Потоки в питоне, как и сам питон, медленные. А ещё и GIL есть.

Значение ты можешь записывать в threadsafe структуры. Например, в список, а в главном потоке проверять, достаточной ли длины он и если нет - спать 0.1 секунду. Не забудь только отлавливать таймауты и ошибки.

P.S. То, чего ты хочешь добиться удобно делается через aiohttp / eventlet
Ответ написан
@asd111
Обычно потоки не возвращают значений, а записывают их в list или куда нибудь ещё.
Я бы ваш пример написал так(кстати в results находятся все скачанные страницы):
from multiprocessing.dummy import Pool as ThreadPool
from pprint import pprint

import requests

pattern = 'http://www.astateoftrance.com/episodes/episode-'
start_url = 700
urls_list = []


def gen_urls(start):
    for i in range(start, 800):
        url = pattern + str(i) + '/'
        urls_list.append(url)


def my_url_get(url):
    result = requests.get(url)
    print("{url} was Downloaded".format(url=url))
    return result


gen_urls(start_url)
pprint(urls_list)

pool = ThreadPool(20)
results = pool.map(my_url_get, urls_list)
pool.close()
pool.join()

pprint(results[0].content.decode('utf-8'))
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы