Задать вопрос
Ответы пользователя по тегу Python
  • Как создать новый словарь, не меняя старый?

    Vindicar
    @Vindicar
    RTFM!
    rows = self.rows
    НО! В тоже время изменяется из self.rows, который является другим списком.

    Не является. Твой оператор просто присвоил переменной rows ссылку на тот же самый список, что и self.rows.
    Это легко проверить оператором is или сравнением id():
    print(rows is self.rows, id(rows) == id(self.rows))  # True True

    Более того, если ты только скопируешь сам список:
    rows = self.rows.copy()
    То всё ещё поймаешь проблемы, так как скопируются ссылки на элементы, а не их значения:
    print(rows is self.rows, id(rows) == id(self.rows))  # False False
    print(rows[0] is self.rows[0], id(rows[0]) == id(self.rows[0]))  # True True

    Тебе нужно сделать глубокую копию (deepcopy). Это можно сделать вручную, так как у тебя всего два уровня вложенности (список-словарь):
    rows = [rowdict.copy() for rowdict in self.rows]
    Для более глубоких уровней есть функция copy.deepcopy(), но у неё есть свои подводные камни. Цитата:
    Two problems often exist with deep copy operations that don’t exist with shallow copy operations:
    Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
    Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.
    Ответ написан
    Комментировать
  • Зачем нужен декоратор @dp и все в этом духе, типо @dp.message_handler() в aiogram?

    Vindicar
    @Vindicar
    RTFM!
    На пальцах: чтобы бот работал, его функции должны вызываться при наступлении определённых событий (например, входящего сообщения). Проблема в том, что aiogram знает о возможных событиях, но ему нужно сказать, какие функции когда вызывать. Обычно это называется "зарегистрировать обработчик".
    В питоне функции - объекты первого рода, т.е. их можно сохранять в переменные, передавать как параметры, возвращать как результат и вообще поступать с ними как с любым другим значением.
    Т.е. по идее можно было бы сделать так:
    async def echo(message: Message):
        text = f"Привет, ты написал {message.text}"
        await bot.send_message(chat_id=message.from_user.id, text=text)
    
    dp.register_function_for_message(echo)  # это не настоящий метод aiogram, только пример

    Тогда каждому объявленному обработчику событий соответствовал бы вызов метода, ответственного за регистрацию этого обработчика.

    Но то же самое можно сделать через декораторы. Декоратор - это сокращённый вызов функции, которая принимает в качестве параметра другую функцию.
    Т.е. вот это
    @dp.message_handler()
    async def echo(message: Message):
        text = f"Привет, ты написал {message.text}"
        await bot.send_message(chat_id=message.from_user.id, text=text)

    абсолютно эквивалентно вот этому
    _decorator = dp.message_handler()
    
    async def echo(message: Message):
        text = f"Привет, ты написал {message.text}"
        await bot.send_message(chat_id=message.from_user.id, text=text)
    
    echo = _decorator(echo)

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

    Vindicar
    @Vindicar
    RTFM!
    split() разбивает по пробельным символам. У тебя в списке list_of_words будет 'Москва.', а не 'Москва' и '.'
    Ответ написан
    2 комментария
  • Почему в приведенном примере есть разница в расположении raise StopAsyncIteration?

    Vindicar
    @Vindicar
    RTFM!
    Я подозреваю, что по исчерпанию self.r (а range() - это не список, это одноразовая последовательность!) попытка вхождения в async for x in self.r приведёт к тому, что self.r просигнализирует об исчерпании последовательности. Как следствие, тело async for не выполнится ни разу, и управление выйдет за цикл. А за циклом - ничего, конец корутины. Поэтому, так как явного return не было, будет неявный return None. Что ты и наблюдаешь.
    Соответственно, ты никогда не получишь выброс StopIteration - его будет выкидывать self.r.__anext__(), но исключение будет перехватываться async for.
    Так что нужно добавить raise StopIteration() после async for, чтобы по опустошению self.r оно гарантировано выбрасывалось.
    Ответ написан
    1 комментарий
  • Aiogram как перейти на другой @dp message_handler()?

    Vindicar
    @Vindicar
    RTFM!
    Что у тебя за каша с вложенными обработчиками? Нет никаких гарантий, что это вообще будет работать.
    Научись пользоваться finite state machine.
    Ответ написан
    Комментировать
  • Как определять количества целых чисел на отрезке, интервале, полуинтервале?

    Vindicar
    @Vindicar
    RTFM!
    Разбей задачу на меньшие.
    1. Научиться разбирать входную строку. Можно регулярными выражениями, можно вручную с помощью split().
    В итоге у тебя должно быть 4 значения: начало интервала, входит ли начало (открытый/закрытый левый край), конец интервала, входит ли конец (открытый/закрытый правый край).
    2. Найти количество чисел в интервале.
    2.1. Округли левый край вверх (math.ceil()) чтобы найти первое целое число, входящее в интервал. Если результат округления равен левому краю И интервал открыт слева, прибавь к числу 1.
    2.2. Округли правый край вниз (math.floor()) чтобы найти последнее целое число. Если результат округления равен правому краю И интервал открыт справа, вычти из числа 1.
    2.3. Зная первое и последнее целое число, входящее в интервал, нужно вычесть первое из последнего и прибавить 1. Т.е. если первое число 2 а последнее 4, то в интервале 4 - 2 + 1 = 3 числа (2, 3, 4).
    Вот и всё. На питон переведёшь самостоятельно.
    Ответ написан
    1 комментарий
  • Как навсегда изменить цвет кнопки при нажатии в Python?

    Vindicar
    @Vindicar
    RTFM!
    Свяжи обработчик событий с кнопкой.
    Заведи глобальную переменную, которая считает, сколько раз была нажата кнопка.
    В обработчике событий читай эту переменную, увеличь её на 1, в зависимости от значения вызывай self.pushButton.setStyleSheet() с разными стилями.
    Ответ написан
    1 комментарий
  • Как правильно использовать run_in_executor?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала посмотри пакет arsenic, это селениум с асинхронной обёрткой. Можно будет переписать твой парсер на асинхронный подход, и не париться по поводу блокировки бота.
    Ответ написан
    Комментировать
  • Как работает перенаправление вывода скрипта python?

    Vindicar
    @Vindicar
    RTFM!
    Скорее всего, проблема в работе с одним файлом через два дескриптора (один - stdout твоего скрипта, второй - stdout вызываемого). Попробуй принудительно сбрасывать данные в файл:
    print('Пытаемся запустить файл 1:', flush=True)
    Ответ написан
    1 комментарий
  • В Pycharm код выполняется, из винды нет, почему?

    Vindicar
    @Vindicar
    RTFM!
    Открой окно терминала (cmd.exe), перейди в каталог скрипта, запусти его командой python myscript.py.
    Тогда окно терминала останется по завершению скрипта, и ты сможешь увидеть, что скрипт написал.
    Ответ написан
    Комментировать
  • Как получить результат выполнения задачи в Asyncio?

    Vindicar
    @Vindicar
    RTFM!
    await tay
    Угадай с трёх раз, что возвращает это выражение?
    Правильно. Значение, которое вернёт корутина, запущенная в рамках задачи. Просто присвой его переменной.
    А вообще в твоём случае и задачи-то не требуются.
    Освой asyncio.gather().
    Она позволит выполнить переданные корутины одновременно, и вернёт массив их результатов.
    results = await asyncio.gather(coro1(x,y), coro2(a,b), ...)
    res1, res2, ... = results
    Ответ написан
    Комментировать
  • Как в Python присвоить объекту класс, если имена классов хранятся в списке?

    Vindicar
    @Vindicar
    RTFM!
    Например, так.
    class KnownClasses:
        # используем статическое поле класса, 
        # так как к нему проще получить доступ из разных модулей
        collection: typing.Dict[str, typing.Type] = {}
    
    class SomeKnownClass:
        ...  # тут тело класса
    
    # регистрируем класс
    KnownClasses.collection[SomeKnownClass.__name__] = SomeKnownClass

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

    Vindicar
    @Vindicar
    RTFM!
    Запустить и пусть работает.

    Не, кроме шуток. Каков вопрос - таков ответ.
    Нужна машина, которая включена и подключена к сети 24/7. Например, арендованная VPS.
    Также нужно предусмотреть наиболее вероятные исключения в боте, отловить и обработать их.
    Также стоит предусмотреть средства аварийного перезапуска. Например, если на VPS установлен Debian-подобный дистрибутив, то можно оформить запуск бота через systemd. Это гарантирует перезапуск программы при перезагрузке, а также при его аварийном завершении.
    Ответ написан
    Комментировать
  • Почему скрипт не принимает переменные?

    Vindicar
    @Vindicar
    RTFM!
    Я подозреваю, что ты не подумал о типах данных.
    Из текстового файла ты можешь прочитать только строковой тип.
    А какой тип данных используют нужные тебе ID?
    Ответ написан
  • TypeError: 'NoneType' object is not subscriptable.?

    Vindicar
    @Vindicar
    RTFM!
    У тебя в твоем json не то, что ты ожидаешь.
    Где именно - нужно проверять по шагам, вместо лихого objects_data.get('data').get('list')[0]
    Действительно ли objects_data словарь? Есть ли там ключ data?
    Действительно ли по ключу data лежит словарь? Есть в этом словаре ключ list (подозреваю что нет)?
    Лови исключения блоком try-except, при исключении скидывай в какой-нибудь файл содержимое проблемного json, чтобы можно было посмотреть, что там тебе прилетело от сервера.
    Ответ написан
    Комментировать
  • Как мне оптимизировать цикл, чтобы он работал намного быстрее?

    Vindicar
    @Vindicar
    RTFM!
    0. Понять, про какой именно цикл речь.
    1. Замерить время выполнения частей цикла.
    2. Найти часть, которая тормозит.
    3. Понять, почему она тормозит.
    4. Написать реализацию, которая будет тормозить меньше.
    5. Проверить её в деле.
    Ответ написан
    Комментировать
  • Почему не работает detectMultiScale python?

    Vindicar
    @Vindicar
    RTFM!
    face_cascade = "C:\mine\haarcascade_frontalface_alt.xml"
    ...
    face_cascade.detectMultiScale(

    У тебя face_cascade - это строка. Чего ты ожидаешь-то от неё? Класс строки понятия не имеет ни про какие каскады Хаара.
    Сдаётся мне, ты пропустил этап собственно загрузки каскада из указанного файла. А именно, вызов конструктора cv2.CascadeClassifier().
    Ответ написан
    1 комментарий
  • Как написать эту программу?

    Vindicar
    @Vindicar
    RTFM!
    Ну тогда...
    str.partition() - для разделения строки на две части по первому указанному разделителю. Пригодится для отделения страны от списка городов.
    str.split() - для разделения строки на неизвестное заранее число частей. Пригодится для разделения списка городов на отдельные названия.
    str.strip() - для удаления пробелов. Пропусти названия городов через этот метод, чтобы убрать лишние пробелы по краям.
    open() - для открытия файла.
    file.readline() - для чтения строки из файла.

    Логика простая.
    1. Создаёшь словарь.
    1. Открываешь файл.
    2. Читаешь строку, преобразуешь в целое - это количество записей.
    3. Организуешь цикл с параметром (число повторов равно количеству записей).
    4. В цикле читаешь строку, режешь её на две части - страна и города.
    5. Режешь список городов на названия.
    6. В цикле по названиям убираешь лишние пробелы из названия, и вставляешь в словарь пару: ключ - название города, значение - название страны.
    7. Конец обоих циклов (и по городам, и по строкам).
    8. Читаешь строку запрос, разбиваешь на части, так же убираешь пробелы.
    9. Для каждого элемента запроса проверяешь, есть ли в словаре такой ключ оператором in. Если есть, выводишь значение по этому ключу.
    Всё.
    Ответ написан
  • Как отсортировать ссылки из одного файла в другой?

    Vindicar
    @Vindicar
    RTFM!
    Если у тебя всего-то тысяча строк, то проще загрузить их все и прогнать через collections.Counter.
    Получишь и список уникальных строк, и сколько раз каждая из них повторяется.
    Ответ написан
    Комментировать