Ответы пользователя по тегу Python
  • Как составить число n из элементов списка?

    @deliro
    Ответ написан
    Комментировать
  • Как запараллелить выполнение ф-ций в асинхронном парсере?

    @deliro
    1. Создать очередь (asyncio.Queue)
    2. Парсер пишет в очередь, писарь csv читает очередь и пишет в неё.
    3. Парсер и писарь должны запускаться одновременно, то есть, типа такого

    q = asyncio.Queue()  # с maxsize можно поиграться, в данном случае отставание писаря от парсера может быть не более чем на один элемент
    await asyncio.gather(get_pages_data(q), csv_writer(q))

    4. Парсеров, кажется, надо сделать больше одного. То есть, появляется второй asyncio.Queue (назовём его work_queue), куда падают lines из файла, эту очередь слушают N воркеров (скажем, 5 штук), получают элемент, работают с ним, затем пишут в result_queue, который слушает писарь csv и записывает результат в файлик

    Псевдокод будет выглядеть так:

    async def file_reader(work_q, n_parsers):
        with open('all_links_1.txt', 'r') as f:
            lines = [line.strip() for line in f.readlines()]
        for line in lines:
            await work_q.put(line)
        for _ in range(n_parsers):  # говорим парсерам, что работы больше нет
            await work_q.put(None)
    
    async def parser(work_q, results_q):
        while True:
            line = await work_q.get()
            if line is None:
                return
            result = ... магия с походом в http ...
            await results_q.put(result)
    
    async def writer(results_q):
        with open('companys.csv', 'w', newline='') as file:  # возможно, открывать файл имеет смысл при каждом получении элемента и закрывать после записи, так файл всегда будет "целым", но процесс записи будет дольше
            writer = csv.writer(file, delimiter=',')
            while True:
                result = await results_q.get()
                if result is None:
                    return
                writer.writerow([result['name'], result['phone'], result['edrpou']])
    
    
    async def main():
        work_queue = asyncio.Queue()
        results_queue = asyncio.Queue(10)  # парсер не должен ждать, пока писарь запишет в файл (хард может быть занят), поэтому небольшой буфер
        n_parsers = 5
        tasks = []
        parsers = []
        reader_task = asyncio.create_task(file_reader(work_queue, n_parsers))
        tasks.append(tasks)
        for _ in range(n_parsers):
            parser_task = asyncio.create_task(parser(work_queue, results_queue))
            tasks.append(parser_task)
            parsers.append(parser_task)
        tasks.append(asyncio.create_task(writer(results_queue)))
        await asyncio.gather(*parsers)  # ждём все парсеры
        await results_queue.put(None)  # говорим писарю, что больше ничего не будет
        await asyncio.gather(*tasks)  # дожидаемся все остальные таски (вернее, будет только одна — writer)


    Однако нужно понимать, что порядок результатов при таком подходе не будет гарантированным или хоть сколько-то стабильным. Поэтому, если порядок важен, стоит писать в файл какую-то промежуточную структуру (пусть тот же csv, но с доп столбцом link) и под конец всех работ вычитывать её, сортировать и складывать уже в нужном порядке
    Ответ написан
  • Как ускорить работу Python в разы?

    @deliro
    Ну ага мы сейчас такие раз и рецепт тебе сказали, который работает для всех случаев. Если бы он был, его бы логично было запихать прям в интерпретатор, не так ли?

    Может быть, asyncio тебе поможет, может быть threading, может быть, там CPU-bound у тебя что-то и надо multiprocessing, а может и вообще на PyPy заменить интерпретатор или часть кода переписать на Cython

    А может вообще сервер стоит подвинуть ближе к серверу API чтобы пинг уменьшить. Или лимиты как-то повысить, используя прокси, несколько аккаунтов или заплатив за API.

    Ну или просто код говно:)

    Нам откуда знать профиль твоей нагрузки? Вариантов тысячи.
    Ответ написан
    1 комментарий
  • Как при помощи pydantic распарсить json?

    @deliro
    Как насчёт почитать документацию? https://pydantic-docs.helpmanual.io/usage/models/
    Ответ написан
    Комментировать
  • Как реализовать класс-обёртку, используя Python generics?

    @deliro
    https://github.com/rustedpy/result

    p.s. непонятно, зачем в твоём варианте ты хочешь смешивать мух с котлетами. Валидным возвращаемым значением вполне может быть объект подтипа Exception, в том числе, ошибкой не обязательно должен быть Exception.Часто гораздо удобней ошибкой делать Enum. (Чувствуешь, как значение и ошибка поменялись местами и твоя проверка not isinstance(result, ServiceException) только что зафейлилась?)
    Ответ написан
    Комментировать
  • Для чего нужна черепашья графика?

    @deliro
    Наглядно увидеть, что твой код что-то делает. Никакой практической ценности это не несёт
    Ответ написан
    Комментировать
  • Micropython uasyncio почему одна функция тормозит другую?

    @deliro
    Во-первых, urequests.get у тебя блокирующая (с micropython не знаком, но await там у тебя нет и не похоже, что возвращается future)
    Во-вторых, ровно каждые 50мс выполняться оно не будет. sleep ставит в хип таску с приоритетом «текущее время» + время сна. Этот хип разбирается на каждом шаге event loop, но никто не гарантирует, что шаг отработает, допустим, не за 500мс, тогда твоя таска исполнится только через полсекунды. Ну и блокирующий вызов urequests это лишний раз подтверждает

    В общем, sleep - это «усни минимум на x времени», а блокирующий вызов http надо заменить на асинхронный
    Ответ написан
    Комментировать
  • Как соединить предложения в выражение, чтобы выражение не превышало 400 символов?

    @deliro
    from itertools import combinations
    
    
    l = ['Python is an interpreted, object-oriented, high-level programming language with dynamic semantics.', 
                'Its high-level built in data structures, combined with dynamic typing and dynamic binding, make it very attractive for Rapid Application Development, as well as for use as a scripting or glue language to connect existing components together.', 
                "Python's simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance.", 
                'Python supports modules and packages, which encourages program modularity and code reuse.', 
                'The Python interpreter and the extensive standard library are available in source or binary form without charge for all major platforms, and can be freely distributed.', 'Often, programmers fall in love with Python because of the increased productivity it provides.', 
                'Since there is no compilation step, the edit-test-debug cycle is incredibly fast.', 'Debugging Python programs is easy: a bug or bad input will never cause a segmentation fault.', 'Instead, when the interpreter discovers an error, it raises an exception.', "When the program doesn't catch the exception, the interpreter prints a stack trace.", 
                'A source level debugger allows inspection of local and global variables, evaluation of arbitrary expressions, setting breakpoints, stepping through the code a line at a time, and so on.', "The debugger is written in Python itself, testifying to Python's introspective power.", 
                'On the other hand, often the quickest way to debug a program is to add a few print statements to the source: the fast edit-test-debug cycle makes this simple approach very effective.'
                ]
    
    def f(lst):
        for i in range(len(lst)):
            r = i + 1
            for picked in combinations(lst, r):
                sentense = " ".join(picked)
                if len(sentense) <= 400:
                    yield sentense
    
    print(list(f(l)))
    Ответ написан
    Комментировать
  • Как правильно написать мультипоточность на питоне?

    @deliro
    Парсинг сайтов чаще всего упирается с IO, а не CPU. 99% времени ты будешь сидеть и ждать ответа от сервера. Ядра тут вообще не нужны. Достаточно в asyncio закинуть тасков на HTTP запросы через какой-нибудь httpx или aiohttp и всё будет прекрасно "одновременно" качаться в одном потоке на одном ядре. А потом разгребать ответы либо синхронно, либо создать пул процессов (ProcessPoolExecutor) и парсить HTML/JSON или что у тебя там в процессах, если CPU вдруг начал нагружаться на 100%

    Потоки в питоне не умеют работать одновременно, нагружая разные ядра процессора, кроме очень исключительных случаев.
    Ответ написан
    Комментировать
  • Как сгенерировать синусоиду питончиком?

    @deliro
    math.sin принимает градус в радианах https://docs.python.org/3/library/math.html#math.sin. Уж можно было подставить пару известных
    Ответ написан
    Комментировать
  • Использование staticmethod в Python это плохая практика?

    @deliro
    Простите, что поздно
    62c5710d23ac5715205098.jpeg
    Ответ написан
    Комментировать
  • Как обойти каптчу?

    @deliro
    Ну допустим, измени код
    Ответ написан
    1 комментарий
  • Как обьеденить 5 json в один на python?

    @deliro
    но толкового примера не нашел

    Потому что его не может существовать физически. JSON нельзя просто склеить. Например, в файле 1.json будет [1,2,3], а в 2.json будет [4,5,6]. Они как должно склеиться? Как [1,2,3,4,5,6] или как [[1,2,3], [4,5,6]]? Если в файле 1.json будет null, а в 2.json будет "2" — как их склеить? Это вообще невозможно. Если в 1.json будет {"a": [1,2,3], "b": 2}, а в 2.json будет {"a": [4], "c": 3}, результат должен быть {"a": [1,2,3,4], "b": 2, "c": 3} или {"a": [4], "b": 2, "c": 3} или [{"a": [1,2,3], "b": 2}, {"a": [4], "c": 3}] или {"a": [[1,2,3], [4]], "b": 2, "c": 3} или как?

    Для конкретного формата JSON нужно установить правила мержа, которые удовлетворяют твоим требованиям.
    Ответ написан
  • Как спарсить данные если нет нормальной пагинации?

    @deliro
    Если последняя страница содержит полностью идентичные ссылки, что и предыдущая — предыдущая была последней
    Ответ написан
  • Вывести случайный ключ из словаря json?

    @deliro
    Вывести случайный ключ из словаря json

    Так ключ или значение? Так из словаря или из JSON?

    Вывести случайный ключ из словаря json

    from random import choice
    choice(list(dct.keys()))
    Ответ написан
  • Как в скрипте Python, во время его работы, переместиться к определенной строчке кода?

    @deliro
    Слава Гвидо, нет
    Ответ написан
    Комментировать
  • Как в функцию, внутри функции map() передать больше аргументов?

    @deliro
    Не надо использовать ни map, ни filter. Эта дурь в питоне совершенно нечитаема (особенно когда вложена друг в друга и не один раз). Вместо того, чтобы написать map(f, iterable), лучше использовать [f(x) for x in iterable]. Ну или если нужно ленивое исполнение, прям как в map, то генератор (f(x) for x in iterable). Точно также, как вместо filter(predicate, iterable), лучше использовать [x for x in iterable if predicate(x)]

    Отвечая на твой вопрос: [f(x, arg2, arg2) for x in iterable] (скобки квадратные, круглые или фигурные — по вкусу)
    Ответ написан
    Комментировать
  • Не нарушает ли данный код концепцию асинхронности?

    @deliro
    Что такое "концепция асинхронности" и что асинхронного в твоём коде (кроме ничего)? Ты просто натыкал async def в рандомных местах.
    Ответ написан
    3 комментария
  • Насколько эффективен мой код, если я для изменения key-value хранилища каждый раз полностью считываю его?

    @deliro
    Для того чтобы считать из него какое-то значение по ключу или добавить новое значение, я считываю его каждый раз его полностью. Это нормальная практика или стоит поступать иным образом?

    Смотря что такое "норма". Если это штука просто на поиграться — нормально. Если в хранилище пара сотен ключей или меньше — нормально. Если нагрузок нет — нормально. Для реальных проектов — не нормально. Сложность каждой операции — O(n), не считая того, что открытие файлов — это тоже затратная операция. SQLite с одной таблицей и индексом на key в качестве key-value хранилища будет в разы быстрее.

    P.S как лучше писать: if smth is None или лучше писать if smth?

    Это две разных проверки. smth is None выдаст False, если smth равно 0 или пустому списку или другому falsy объекту. Я предпочитаю писать is None всегда, когда тип Optional[T], чтобы исключить случай, когда пришёл не-None, но falsy значение, иначе можно скрыть ошибку
    Ответ написан
    1 комментарий
  • Как сделать генератор из чисел и букв не рандомный?

    @deliro
    import string, itertools
    
    itertools.combinations_with_replacement(string.digits + string.ascii_lowercase[:11], 3)
    Ответ написан