TGTGInsighttelegram intelligenceLIVE / telegram public index
Назад кон каналите
Python Заметки avatar

TGINSIGHT CHAT

Python Заметки

@pythonotes

Education

Интересные заметки и обучающие материалы по Python Контакт: @paulwinex ⚠️ Рекламу на канале не делаю!⚠️ Хештеги для поиска: #tricks #libs #pep #basic #regex #qt #django #2to3 #source #offtop

Претплатници2,220Тековни претплатници
Следени објави384Број на индексирани објави
Неодамнешен опфат23,490Збир на неодамнешни прегледи
Неодамнешни објави

Неодамнешни објави

Страница 12 од 32 · 384 објави

Објавено 18 авг.

Что-то вы гоните насчет "привычного вида формата 755 и 644". Я вот вообще не понял что это!😳 Действительно, что означают цифры которые мы получили в прошлом посте? Это кодировка, заключающая в себе режимы доступа к файлу. Подробней можно почитать в статье про chmod. Там можно увидеть альтернативное обозначение того же самого с помощью символов r w x, что значит чтение, запись, исполнение. Чтобы преобразовать восьмеричное число в такое обозначение в Python есть готовая функция >>> stat.filemode(0o755) '?rwxr-xr-x' Мы видим 3 группы по 3 символа, дающие 3 типа доступа для 3 типов юзеров. А что за знак вопроса в начале? Давайте передадим в эту функцию необрезанное значение от os.stat >>> stat.filemode(os.stat(path).st_mode) 'drwxr-xr-x' Это данные, которые мы безжалостно обрезали в прошлый раз😼 Первый символ обозначает тип объекта. Это может быть файл (-), директория (d) или симлинк (l). Вот простая схема данной кодировки [1][3][3][3] │ │ │ │ │ │ │ └──> Others Permissions │ │ └─────> Group Permissions │ └────────> Owner Permissions └───────────> File Type (разверните экран если вы с телефона) Если вы попробуете получить пермишены для симлинка то получите пермишены для файла >>> path = '.venv/bin/python3' >>> stat.filemode(os.stat(path).st_mode) '-rwxr-xr-x' Чтобы получить свойства именно симлинка, нужно это явно указать >>> stat.filemode(os.stat(path, follow_symlinks=False).st_mode) 'lrwxrwxrwx' #tricks#basic

2,280 views

Објавено 16 авг.

Как получить значение прав доступа к файлу в виде привычного формата записи 755 или 644? В целом, способ вот такой: >>> path = '...' >>> print(oct(os.stat(path).st_mode & 0o777).split('o')[-1]) '755' Теперь разберёмся что всё это значит. До того как мы сделали split() строка была следующего вида: 0o755 Что это за тип данных? Это тип int в восмиричной системе исчисления. Для преобразования в такой формат есть builtin функция oct() >>> oct(493) '0o755' Как видите, результат возвращается виде строки. Но это не мешает нам создавать переменные синтаксисом восьмеричных чисел, то есть с префиксом 0o. Хотя, при распечатке мы всё равно получим int. >>> x = 0o777 >>> print(x) 511 Преобразовать эту строку в int можно функцией int(), указав базис 8 >>> int('0o755', 8) 493 Теперь посмотрим что нам возвращает os.stat >>> perm = os.stat(path).st_mode 33261 Преобразуем в oct >>> oct(perm) '0o100755' Уже почти то что надо. Чтобы оставить только нужное, отрезаем лишнее с помощью оператора & (AND). Для этого последние 3 значения ставим максимальными, остальные нулевыми. >>> perm & 0o777 493 Оператор работает с бинарным представлением чисел, то есть операция была вот такая: 0b100000111101101 & 0b111111111 = 0b111101101 Вспоминаем побитовые операторы Остаётся преобразовать в восьмеричное представление и убрать префикс >>> oct(493) '0o755' >>> oct(493).split('o')[-1] '755' Именно в таком виде пермишены файла в коде обычно не используются. Хранить и использовать их удобно в виде восьмеричного int os.chmod(path, 0o755) или строки os.chmod(path, int('0o755', 8)) А зачем в строке если достаточно в int? Наприрмер чтобы в json была удобочитаемая запись. Так как сериализатор запишет восьмеричное число как обычный десятичный int >>> json.dumps(0o755) '493' Поэтому для удобства пишем его строкой а потом преобразуем в восьмеричный int. #tricks

1,750 views

Hashtags

Објавено 13 авг.

Сегодня на Github закрывается доступ к git-операциям по паролю. Теперь доступ только по токену. Для входа на сайт следует настроить двухфакторку. #offtop

1,840 views

Hashtags

Објавено 4 авг.

У Python есть очень удобная штука - стек вызовов. Благодаря нему модуль traceback может показать где и что сломалось в момент выброса исключений. Но иногда Python просто падает без какой-либо информации. Лично меня это регулярно настигает на Windows и очень бесит. Совершенно не понятно что где произошло и как искать причину. Ставить сишные дебаггеры? Чтобы быстро понять в какой строке ошибка иногда достаточно использовать встроенный модуль faulthandler Базовое использование очень простое: python.exe -q -X faulthandler main.py Если интерпретатор упадёт, то вы хотя бы узнаете какая строчка привела к такому событию. Попробуйте уронить Python без faulthandler и с ним. #libs#tricks

2,590 views

Hashtags

Објавено 2 авг.

А вы ждёте выхода Python 4? Ну зря ждёте😭 По словам Гвидо, ему хватило проблем с переходом со 2го на 3й) Лучше постепенно развивать имеющийся функционал с полной совместимостью кодовой базы чем делать такие резкие изменения. Велика вероятность что выше 3 мажорная версия более не поднимется. А как же обещания про невероятные ускорения в Python 4? Очевидно, что теперь они все будут добавляться в 3ю ветку. Вот здесь можно почитать про планы ускорения где Гвидо обещает скорость 2х уже в 3.11 и х5 через 4 года! Здесь можно посмотреть следующие шаги по оптимизации. #offtop#2to3

2,270 views

Hashtags

Објавено 30 јул.

Модуль objgraph позволяет нарисовать граф объектов со связями между ними. По такому визуальному представлению иногда удобно дебажить архитектуру вашего кода. Особенно когда построение структуры происходит динамически. Не ставьте слишком большую глубину прорисовки, я как-то поставил 50 и ждал пол часа пока движок отрисует мне 3к нод. Вряд ли в таком графе можно что-то разобрать. К тому же рендер падает с ошибкой dot: graph is too large for cairo-renderer bitmaps. И просит уменьшить скейл до 0.2, а значит даже текста не разобрать. Так что глубина 3-5 вполне достаточно. #libs

1,970 views

Hashtags

Објавено 26 јул.

В стандартном модуле random есть две очень похожие функции random.randint() random.randrange() Обе возвращают случайное значение из указанного диапазона >>> random.randint(10, 20) 12 >>> random.randrange(10, 20) 17 В чем же отличие? Дело в том что у randrange() есть третий параметр step. randint() действительно возвращает случайное число из указанного диапазона. randrange() на первый взгляд делает тоже самое если передать также два параметра. Но есть указать еще и step то наш диапазон усложняется, то есть в него попадёт не полный ряд значений. Например, я хочу получить случайное значение из диапазона но только чётное число. Тогда достаточно сделать так: >>> randrange(10, 20, 2) 16 Таким образом получается что randint это частный случай randrange без указания параметра step. Еще одно важное отличие в том, что randint() включает в диапазон второе значение а randrange() нет. То есть выражение randrange(10, 20) никогда не вернёт 20, а randint(10, 20) вернёт. #tricks#basic

1,950 views

Објавено 14 јул.

Наверняка у многих возникло желание потестить отправку сообщений, но Redis не установлен и вообще непонятно как с ним быть. На самом деле запустить его очень просто. 🔸 Для Windows, качаем архив, запускаем redis-server.exe 🔸 Для Linux несколько команд 🔸 Если есть Docker, то еще проще docker run --rm -p 6379:6379 redis Всё, можно экспериментировать! ______________________ А еще с сервером можно поиграть в пинг-понг > redis-cli ping PONG #tricks#libs#linux

1,890 views

Објавено 12 јул.

Самый большой минус синхронизации из прошлого поста - нестабильность. Не знаю как у вас а у меня эта штука падала несколько раз) По моему не очень production-ready. Что же делать? Отправлять disckcache на сетевой диск? Не, я бы не стал. Ведь есть отличная альтернатива! Это Redis. Redis это жутко быстрая in-memory база данных. Запись в неё похожа на документоориентированные NoSQL базы данных. То есть без схемы, без таблиц. Просто ключ=значение. Redis используется для кэширования и как брокер для передачи сообщений. Имеется подписка на изменения и время жизни записей. Вот пример кода: import redis R = redis.Redis() R.set('key', 'value') R.get('key') # b'value' Имея такой функционал, давайте реализуем что-то очень удобное для обмена данными по сети... Хотя подождите ка, всё уже придумано до нас! И это проект PyRSMQ Что он делает? Создаёт очередь сообщений которые может забирать другой клиент. Как это организовать? Для начала поднимаем cервер Redis. Потом на одном хосте создаём очередь для отправки. queue = RedisSMQ( host=host, port=port, qname='example' ) queue.exceptions(False).\ createQueue(delay=0).\ vt(message_live_time).\ execute() На другом хосте содаём клиента для прослушивания очереди on_receive = lambda msg: print(msg) consumer = RedisSMQConsumer( 'example', on_receive host=host, port=port) Начинаем прослушивание очереди consumer.run() Теперь можем отправлять сообщения queue.sendMessage(delay=0).message(msg).execute() Теперь все сообщения, отправленные в очередь, будут попадать в наш колбек on_receive . ▫️Обязательное условие — наличие поднятого Redis-сервера. ▫️Единственное ограничение, обусловленное спецификой инструментов, данные должны быть JSON serializable. #libs

1,930 views

Hashtags

Објавено 9 јул.

От многопоточных вычислений переходим к распределённым. То есть вычисления, происходящие на нескольких компьютерах. Конечно, в зависимости от задачи, вы можете взять готовые решения вроде CGRU или Deadline для рендеринга, charm4py или Dask для ML, или замутить что-то на AWS С2. Но хотелось бы чего-то попроще, попитоничней что ли) А ведь в Python есть средства "из коробки" для синхронизации нескольких процессов на разных хостах. Вот простой пример кода, который синхронизирует работу двух процессов на разных компьютерах. В этом случае используется процесс-посредник, который является синхронизирующим сервером. В примере создаётся некий Manager, который шарит общую для клиентов очередь. Все подключившиеся могут что-то в неё писать или забирать. В моём коде один процесс что-то "считает" и складывает в очередь, другой забирает и продолжает какие-то свои "расчёты". Если у вас есть несколько машин, то можете попробовать это запустить по сети (нужно заменить 'localhost' на IP-адрес сервера). Но и на локальной машине сработает. Gist 🌎 #libs#source#tricks

1,720 views

Објавено 7 јул.

­Возможно, стоит пояснить разницу между синхронизацией из thread/process-safe и синхронизацией с помощью Lock🤔 Наша задача — заставить разные процессы и потоки обращаться к базе данных (или любым другим ресурсам) последовательно. Чтобы не случилось так называемого race condition, то есть состояние гонки. Это когда разные потоки или процессы пытаются одновременно что-то сделать с одним и тем же ресурсом. В этом случае нам нужна какая-то логика ограничения. Пока один процесс не завершил своё действие, другие не могут получить доступ к ресурсу. Так вот, thread-safe и process-safe означает что отдельно взятые операции записи в БД гарантированно будут последовательны. Запросы из разных процессов или потоков выстроятся в очередь и не будут мешать друг другу. Лучше всего когда этот блок реализован на уровне БД в виде атомарных операций или ещё как-то. Но зачем нам тогда еще дополнительный Lock? Этот способ синхронизации используется когда процесс никак не укладывается в одно действие и должен сделать множество операций прежде чем дать доступ следующему. В этом случае процесс ставит некий глобальный Lock на ресурс и никто другой, даже получив законное право на доступ, не может ничего сделать. Все ждут пока этот Lock не будет снят. Это решается на уровне приложения и правильность реализации полностью в вашей ответственности. Например, если забыли разблокировать или сделали перекрёстный Lock (Deadlock как на картинке), то всё зависнет в бесконечном ожидании. #basic

1,680 views

Hashtags

Објавено 5 јул.

Если вы писали когда-либо мультипоточные или мультипроцессорные приложения то вы знаете какая самая большая проблема у таких программ. Это конечно же синхронизация (мы сейчас не про GIL). Что такое синхронизация? Это когда параллельно работающий код может делать расчёты абсолютно независимо, но вот к общим данным они должны обращаться последовательно в определённом порядке. То есть нужна синхронность вместо асинхронности. Пока один процесс открыл файл, другие просто ждут своей очереди. Пока один поток обновляет переменную, другие просто спят, опять же ждут своей очереди. В Python есть стандартные средства для синхронизации. Это так называемые мьютексы с различной логикой. Например Lock, Semaphore или очередь Queue. Все они работают в контексте одного интерпретатора. То есть все потоки или процессы должны быть запущены из одной программы. Тогда можно использовать один Lock между потоками и общую память между процессами. Но что же делать, если процессы независимы? То есть я просто запускаю два разных интерпретатора с разным кодом. Возможно даже разных версий Python. В моём случае мне потребовалось писать некоторый кеш из одного модуля, который работает совершенно в разных приложениях как вспомогательный инструмент. Сначала я пытался что-то сделать на основе shelve, но потом нашел отличную библиотеку diskcache. Этот проект покрыл все мои потребности: ▫️ thread-safe и process-safe То есть можно выполнять команды из разных процессов и потоков и они всегда будут синхронизированы. Можно писать из разных процессов не опасаясь получить ошибку о том что файл занят другим процессом (как это бывает с shelve) ▫️всегда атомарные операции Это значит что любое действие выполняется в один запрос. ▫️безсерверный Не требуется отдельный процесс для синхронизации. Всё решается через базу данных. Полный список возможностей Из удобных фичей можно еще отметить встроенный Lock, позволяющий синхронизировать независимые процессы. Это как раз то что я искал! На что стоит обратить внимание: 🔸 несовместимы версии python 2 и 3 из-за разницы протоколов pickle 🔸 надёжность работы с сетевыми дисками под вопросом, я бы не стал. Но тут скорей вопрос к сети чем к софту. 🔸 при создании инстанса diskcache.Cache() все данные пишутся в рандомную директорию в temp. Чтобы синхронизировать разные процессы следует указывать одинаковый путь diskcache.Cache(some_path). #libs

1,620 views

Hashtags

12•••1011121314•••20•••303132
ПретходнаСтраница 12 од 32Следна