Задать вопрос
Ответы пользователя по тегу Python
  • Снижается версия Python почему?

    Vindicar
    @Vindicar
    RTFM!
    Нужно немножко включить голову и почитать про то, как работает SSH и оболочка Unix системы. Гуглинг типа "SSH keep program running" быстро бы вывел тебя на то что нужно.
    1. Когда ты подключаешься по SSH, сервер запускает копию bash или sh (или какая там оболочка используется) с правами твоего пользователя.
    <br>
    sshd<br>
      - bash<br>

    При вводе команды в этой оболочке программа ищется в системном PATH, а в нём находится второй питон.

    2. Потом, когда ты делаешь activate, ты переходишь в виртуальное окружение. Оно отличается тем, что питон там ищется по умолчанию другой, так как там поменян PATH (и ещё кое что). И происходит этот переход за счёт запуска дочерней командной оболочки.
    <br>
    sshd<br>
      - bash<br>
          - activate <br>
              - bash<br>


    3. Ты запускаешь свой скрипт. Он запускается из под оболочки внутри activate.
    <br>
    sshd<br>
      - bash<br>
          - activate<br>
              - bash<br>
                  - python3 your_script.py<br>


    4. Ты закрываешь putty. SSH сервер регистрирует отключение клиента, и посылает дочернему bash сигнал HUP - обычно он интерпретируется как сигнал на завершение. Тот передаёт этот сигнал своему дочернему процессу, и так далее.
    <br>
    sshd "sshd: эй, bash, завершайся"<br>
      - bash "bash: эй, activate, завершайся. А теперь я сам завершусь."<br>
          - activate "activate: эй, bash, завершайся. А теперь я сам завершусь"<br>
              - bash "bash: эй, python3, завершайся. А теперь я сам завершусь"<br>
                  - python3 your_script.py "python3: хорошо, завершаюсь."<br>

    В итоге получаем только работающий ssh сервер
    sshd
    И когда ты переоткрываешь сессию, activate уже перестал существовать, и ты снова попадаешь в обычный bash, где в PATH прописан только второй питон.

    Теперь главное: как же это обойти? Нужно сделать так, чтобы python3 проигнорировал сигнал о завершении. Есть несколько способов.
    Самый простой - использовать такой синтаксис:
    nohup python3 your_script.py &
    Амперсанд в конце означает "запусти программу и вернись в оболочку, не дожидаясь когда программа закончит работать". А команда nohup запускает указанную программу с указанными аргументами, но при этом она проигнорирует сигнал HUP, т.е. "эй, завершайся". А потому когда ты закроешь putty, бот должен остаться работать.
    Минус - после переподключения ты не будешь видеть вывод бота в консоль. Так что пиши логи!
    Чтобы остановить бота, придётся использовать ps чтобы узнать ID его процесса, и kill чтобы этот процесс прибить. Ну или можешь предусмотреть команду выхода в самом боте, которая завершит работу скрипта изнутри. Это удобнее.

    Второй способ - использовать программу screen, если она установлена. Документацию по ней гугли. Если коротко, screen позволяет создать виртуальную рабочую сессию, к которой можно подключатсья и отключаться, не прерывая её. При этом весь вывод на экран сохраняется между переподключениями. Удобно если бот пишет много в консоль, но несколько муторно, и надо учить сочетания клавиш.

    Третий способ - сделать так, чтобы бот запускался при загрузке, через init.d скрипт или systemd модуль. Но так как у тебя минимальные права, скорее всего это не прокатит.
    Ответ написан
    1 комментарий
  • Пишет лишнюю букву?

    Vindicar
    @Vindicar
    RTFM!
    А зачем тебе вообще цикл for i in password:?
    Если тебе нужно в консоль и в файл вывести одно и то же, то выполни F.write(f'{n} {password}\n') и всё.
    Ну и приём с with, который я показал в твоём предыдущем вопрос, тоже стоит применить.
    Ответ написан
  • Текст накладывается сам на себя?

    Vindicar
    @Vindicar
    RTFM!
    Добавлю, что
    F.close
    Не делает ровным счётом ничего, так как вы не вызываете метод close.
    Должно быть
    F.close()
    А ещё лучше заменить вот это:
    F = open("txt","w")
      for i in password:
        F.write(str(n)+ password + '\n')
        F.close

    На вот это
    with open("txt","w") as F:
        for i in password:
          F.write(str(n)+ password + '\n')
    Ответ написан
    Комментировать
  • Как сделать чат для трех и более компьютеров в python socket?

    Vindicar
    @Vindicar
    RTFM!
    Выдели кому-то роль сервера, пусть он слушает соединения и хранит список уже подключенных клиентов.
    По приёму сообщения от подключенного клиента, нужно переслать его всем, кроме отправителя.
    Клиенты просто слушают сообщения от сервера и выводят на экран.
    Альтернатива - использовать широковещательный UDP, но TCP-сервер надёжнее.

    Я бы посоветовал разобраться с asyncio, оно может сильно упростить написание сервера.
    Самое сложное будет написать клиента, так как нужно будет подружить asyncio с пользовательским интерфейсом клиента. Даже элементарный input() будет нетривиально использовать.
    Так что можно сразу использовать qasync, чтобы подружить pyqt и asyncio.
    Ответ написан
    Комментировать
  • Как обработать ошибку в discord.py, при неправильном заполнении типа данных?

    Vindicar
    @Vindicar
    RTFM!
    Используй обработчик ошибок, как показано тут. Будет что-то типа такого
    from discord.ext.commands import CommandError, ConversionError
    
    #обработчик команды
    @bot.command() 
    #черная магия discord.py анализирует type hints чтобы понять, как парсить входное сообщение
    async def plus(ctx, x: int, y: int): #указываем, что параметры команды - это целые числа
        z = x + y
        await ctx.send(f"{x} + {y} = {z}")
    #обработчик ошибки
    @plus.error
    async def plus_error(ctx, error):
        if isinstance(error, ConversionError):
            await ctx.send(f"Ошибка преобразования аргументов plus. Вы ввели не числа?")
        elif isinstance(error, CommandError):
            await ctx.send(f"Ошибка выполнения команды plus")
        else:
            await ctx.send(f"Неизвестная ошибка выполнения команды plus")
    Ответ написан
    Комментировать
  • Как изменить название кнопки с командой shell?

    Vindicar
    @Vindicar
    RTFM!
    smokedevil666, сделай глобальный словарь вида
    commands = { "Нажми": "python3 /foor/bar/baz" }
    И ищи в нём полученное сообщение. Если такого ключа нет, ругаешься на пользователя.
    Ответ написан
    8 комментариев
  • Почему выходит ошибка TypeError: list indices must be integers or slices, not str?

    Vindicar
    @Vindicar
    RTFM!
    А ты уверен, что в s1_json корневой элемент - словарь, а не список?
    Ну и то же самое про s_json.
    Ответ написан
    Комментировать
  • Почему в .exe файле программы (Pyqt5) не исполняются команды к sqlite3?

    Vindicar
    @Vindicar
    RTFM!
    > Таблица это сама есть, базу данных я перебросил в корень с исполняемым файлом.
    Т.е. ты не пытаешься запаковать БД, так?
    А ты уверен, что скрипт её находит? Указываешь полный путь до файла с БД? Или как всегда, относительный, и авось текущая рабочая директория будет правильной?
    Просто некоторые py -> exe упаковщики при запуске экзешника распаковывают скрипт во временный каталог, и работают оттуда... а тогда файл БД окажется не рядом со скриптом. Не помню, делает ли так py2exe, выясни.
    Ответ написан
    7 комментариев
  • Почему я получаю 'referenced before assignment'?

    Vindicar
    @Vindicar
    RTFM!
    Питон видит, что ты присваиваешь start_id что-то, и решает что это локальная переменная. А потом понимает, что ты выше её читаешь, и ругается. Это намеренное поведение, так как в противном случае либо:
    а) до присваивания бы читалось значение глобального start_id, а после - локального,
    б) глобальная переменная всегда изменялась бы вместо локальной, и появление новой глобальной переменной с тем же именем что и локальная где-то в функции приводило бы к её неожиданному изменению.
    И то и то неочевидно и могло бы привести к "молчаливому"(без исключений) но неправильному поведению программы.

    Если не присваивать, то локальной переменной start_id не существует, и чтение осуществляется из глобальной.

    Если так надо менять глобальную переменную, то явно пропиши её в начале функции как global start_id.
    А лучше не используй глобальные переменные без нужды. Если их более одной, стоит переделать это в класс.
    Ответ написан
    Комментировать
  • Обработка видео на пайтон. Соединить фото в видео. Как сделать?

    Vindicar
    @Vindicar
    RTFM!
    Ответ написан
    Комментировать
  • Как сделать рассылку сообщения сразу во все каналы?

    Vindicar
    @Vindicar
    RTFM!
    Как-то так. Никаких гарантий, что дискорд не пошлёт твоего бота далеко и надолго за спам.
    @client.command()
    async def test(ctx):
        await ctx.author.send(f'test')
        # сохраняем набор и порядок каналов на случай, если он поменяется в процессе отправки.
        channels = list(ctx.guild.text_channels)
        # формируем пачку корутин, выполняющих отправку
        send_coroutines = [channel.send('test') for channel in channels]
        # планируем одновременное выполнение этих корутин и ждём завершения. 
        # Исключения будут возвращены наравне с результатами, а не выброшены.
        results = await asyncio.gather(*send_coroutines, return_exceptions=True)
        # анализируем results на предмет ошибок. 
        # Успешная отправка вернёт объект сообщения, неудачная вернет (а не выбросит!) объект исключения.
        failed = [ (ch.name, str(res)) for res, ch in zip(results, channels) if isinstance(res, (Exception, asyncio.CancelledError)) ]
        if failed: # были ошибки?
            await ctx.author.send('Failed to send to the following channels:\n' + '\n'.join(f'- {ch}: {msg}' for ch, msg in failed))
        else: # ошибок не было
            await ctx.author.send('Message has been spammed successfully.')
    Ответ написан
    Комментировать
  • Как переделать условие на python 3.10?

    Vindicar
    @Vindicar
    RTFM!
    Дело не в версии питона, а в том что у тебя для первого i в i['key'] не содержится строка "full.zip". В этом случае питон 3.9 даст точно такую же ошибку, так как первый if не отработает, а второй обратится к time_create.
    А вот почему так - уже совсем другой вопрос. Может, разные пакеты установлены на двух версиях питона. Может, просто файлы в files_dict оказываются в немного разном порядке. Я бы посоветовал починить алгоритм в целом, т.е. инициализировать time_create каким-то значением до цикла.
    Ответ написан
    3 комментария
  • Почему не работает запрос mysql?

    Vindicar
    @Vindicar
    RTFM!
    AlexSeley, засунь ошибку в автопереводчик, раз английского не знаешь.
    telebot пытается вызвать твою функцию start() с одним параметром, хотя с точки зрения питона она параметров не принимает.
    Mysql тут нипричем от слова совсем, можешь убедиться, заменив содержимое start() на pass.
    Так что вопрос "почему питон думает, что функция start() не принимает параметров".
    И вот тут уже нужен полный код бота. Оформленный как положено, а не просто копипаст.
    Ответ написан
    Комментировать
  • Ошибка при логировании в консоль после переопределения лога. Как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Ну то что дважды логирует - может, потому что ты не отключил дефолтовый логгер для unicorn.
    Перенастрой журналирование так, чтобы в тексте показывалось имя логгера, будет понятнее кто и что пишет.
    Ответ написан
  • Как убрать ошибку при выведении в окно типа text из текстового файла docx?

    Vindicar
    @Vindicar
    RTFM!
    if var == 0:
    Так не сработает. Нужно
    if var.get() == 0:
    Ответ написан
    Комментировать
  • Как достать значение объекта из json?

    Vindicar
    @Vindicar
    RTFM!
    data - это словарь, а не список. Будь внимателен.
    А у словаря перебираются ключи, а не значения.
    Так что либо так:
    for key in data:
        print(data[key]["bar"])

    Либо так:
    for value in data.values():
        print(value["bar"])
    Ответ написан
  • Как максимально просто и быстро переименовать файлы по маске?

    Vindicar
    @Vindicar
    RTFM!
    1. Составляешь список интересующих тебя файлов с помощью модуля glob или pathlib.
    2. С помощью регулярного выражения "\d+" (модуль re), вытаскиваешь из имен файлов последовательности цифр. Если их несколько, тебе придётся придумать критерий, какую брать (например, последнюю). Определяешь наибольшее количество разрядов.
    3. Снова проходишься по списку имен с помощью re.sub(). Второй аргумент re.sub() может быть не только строкой для замены, но и функцией - просто делаешь функцию, которая дополняет входящую строку нулями до желаемой ширины и возвращает её.
    4. Если новая строка (с заменой) отличается от оригинальной, то переименовываешь файл с оригинальным именем в файл с новым именем, иначе оставляешь как есть.
    Ответ написан
    Комментировать
  • Как лучше хранить пути к файлам в модуле?

    Vindicar
    @Vindicar
    RTFM!
    Пути к каким файлам, собственно?
    Я бы делал их относительными, и при старте сшивал с путём, по которому лежит скрипт. В принципе можно эту логику вынести в отдельный класс, если хочешь.
    Ответ написан
    Комментировать
  • Как сделать такое?

    Vindicar
    @Vindicar
    RTFM!
    discord.py не поддерживает слэш команды, посмотри в сторону dislash - она вроде спроектирована для работы совместно с discord.py.
    Либо можно посмотреть в сторону форков discord.py, типа pycord или nextcord.
    Ответ написан
    Комментировать
  • Как в If записать промежуток между 1 и 35?

    Vindicar
    @Vindicar
    RTFM!
    if 1 <= int(HP) <= 35:
        aboba()
    Ответ написан