Михаил Омельченко | AI&IT
5.28K subscribers
976 photos
192 videos
4 files
713 links
ИИ в работе, разработка, веб. Агенты, автоматизация, инструменты. Веду я, Михаил Омельченко, внешний технический директор по ИИ и ментор.

Менторство, реклама и сотрудничество: djwoms.ru
Telegram - @DJWOMS
YouTube - https://www.youtube.com/c/DjangoSchool
Download Telegram
Мета-классы в Python - это специальные классы, которые позволяют вам изменять поведение и создание других классов. Они предоставляют мощный инструмент для метапрограммирования, т.е. создания кода, который может изменять или дополнять себя во время выполнения.

Одной из главных причин использования мета-классов является облегчение повторяющихся задач, связанных с определением классов. Например, если вы хотите добавить определенное поведение ко всем классам в вашем проекте, можно использовать мета-классы для автоматического применения этого поведения ко всем создаваемым классам.

Помимо этого, мета-классы могут быть полезны для проверки и валидации данных, передаваемых в классы. Вы можете определить специальные методы в мета-классе, которые будут вызываться при создании экземпляров классов, и выполнять необходимые проверки или трансформации.

Кроме того, мета-классы также могут использоваться для расширения стандартных функций языка Python. Например, вы можете использовать мета-классы для добавления дополнительных атрибутов или методов к встроенным классам, таким как список или словарь.

Мета-классы в Python - это мощный инструмент, который позволяет улучшить код и добавить новые возможности к вашим классам. Хотя изначально может быть немного сложно разобраться в этой концепции, она становится все более понятной по мере продвижения в изучении программирования. Используйте мета-классы, чтобы сделать ваш код более гибким, модульным и поддерживаемым.

Пример использования мета-классов в Python.

Представим, что у вас есть класс Person, и вы хотите автоматически добавить атрибут full_name, состоящий из имени и фамилии, ко всем создаваемым экземплярам класса. Вы можете сделать это с помощью мета-класса.

Вот как это может выглядеть:

class PersonMeta(type):
def __init__(cls, name, bases, attrs):
super().__init__(name, bases, attrs)
cls.full_name =
f"{attrs['first_name']}
{attrs['last_name']}"

class Person(metaclass=PersonMeta):
first_name = "John"
last_name = "Doe"

person = Person()
print(person.full_name) # Вывод: John Doe


В этом примере мы создаем мета-класс PersonMeta, который наследуется от встроенного type. В методе __init__ мета-класса мы добавляем атрибут full_name к классу Person, который формируется из значений атрибутов first_name и last_name.

Затем мы определяем класс Person и указываем мета-класс PersonMeta в качестве его мета-класса с помощью аргумента metaclass.

При создании экземпляра класса Person, атрибут full_name автоматически добавляется к экземпляру и содержит значение "John Doe".

#python
👍26❤1🍌1
Привет всем!

Сегодня я хотел бы рассказать вам о таком понятии, как "хеш-функция". Звучит сложно, но я постараюсь объяснить все простым языком.

Хеш-функция - это математическая операция, которая принимает на вход данные любого размера и преобразует их в фиксированную строку определенной длины, которую называют "хешем". Важно отметить, что хеш-функция всегда возвращает одинаковую длину хеша, независимо от размера входных данных.

Зачем нужны хеш-функции? Одно из главных применений хеш-функций - это обеспечение целостности данных. Когда мы передаем данные через интернет или храним их на компьютере, мы хотим быть уверены, что эти данные не были изменены. Вот где хеш-функции приходят на помощь.

Каждый файл, пароль или текст имеют свой уникальный хеш. Как только данные изменяются, например, если файлу добавляются или изменяются символы, его хеш также изменяется. Это делает хеш-функции надежным инструментом для обнаружения даже минимальных изменений в данных.

Хеш-функции также широко используются для шифрования данных и проверки целостности паролей. Важно понимать, что хеш-функции работают в одностороннем порядке, то есть нельзя восстановить исходные данные из хеша. Это делает их безопасными для хранения паролей, так как даже при утечке базы данных злоумышленники не смогут узнать настоящие пароли.

Интересно, что хеш-функции широко применяются не только в IT, но и в других областях. К примеру, они используются в криптографии, а также в блокчейне для обеспечения безопасности транзакций.


🔥Провожу индивидуальные занятия по python и веб разработке (django, fastapi, flask, javascript и т.д.).
Обучаю с нуля, а так же провожу консультации для мидлов и синьоров.

Пишите -  https://t.me/DJWOMS
🔥11👍3🍌1
В комментариях задали вопрос:

"А такой вопрос: те, кто создавал функцию хеширования, знают, как она устроена
Почему же этот процесс необратим - можете рассказать вкратце, пожалуйста."

Как оказалось просто не ответить, но я постараюсь несколькими постами раскрыть этот вопрос.

Процесс хеширования является необратимым из-за основных свойств, которыми обладают криптографические хеш-функции, такие как односторонность и устойчивость к коллизиям.

Односторонность: Криптографические хеш-функции обладают свойством односторонности, что означает, что на данный момент не существует эффективных алгоритмов для обратного преобразования хеш-значения обратно в исходные данные. Это связано с тем, что хеш-функции работают весьма сложными математическими операциями, которые позволяют эффективно преобразовывать данные в хеш, но в обратном направлении этот процесс вычислительно невозможен.

Устойчивость к коллизиям: Хэш-функции построены таким образом, чтобы уменьшить вероятность возникновения коллизий - ситуаций, когда двум разным наборам данных соответствует одно и то же хеш-значение. Хорошие хеш-функции обладают свойством равномерного распределения хеш-значений, что делает эти коллизии очень маловероятными при достаточной длине хеша.

Используя эти два свойства, хеш-функции обеспечивают необратимость:

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

Стоит отметить, что существуют методы атак, такие как метод "грубой силы" (brute force), статистические атаки и атаки на коллизии, которые могут попытаться восстановить исходные данные с помощью сложных алгоритмов и вычислительной мощности. Поэтому для обеспечения безопасности и целостности данных, важно выбирать надежные алгоритмы, такие как SHA-256, SHA-384, SHA-512 и другие.
👍11🔥3❤2
SQL-транзакция - это последовательность операций базы данных, которые выполняются как единое целое.

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

Во время выполнения транзакции, все операции либо успешно выполняются и вносят изменения в базу данных, либо ни одна операция не выполняется и все изменения отменяются. Это позволяет обеспечить согласованность данных, в случае ошибки во время выполнения операций.

SQL-транзакции обычно поддерживаются СУБД (системой управления базами данных), которая обеспечивает механизмы для начала, фиксации или отката транзакции. Например, в MySQL это можно сделать с помощью команд BEGIN, COMMIT и ROLLBACK.

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


🔥Провожу индивидуальные занятия по python и веб разработке (django, fastapi, flask, javascript и т.д.).
Обучаю с нуля, а так же провожу консультации для мидлов и синьоров.

Пишите -  https://t.me/DJWOMS

#sql #бд
👍10😨2❤1
Всем привет!
Сегодня мы поговорим о понятии ACID.

ACID представляет собой сокращение от английских слов: atomicity (атомарность), consistency (согласованность), isolation (изоляция) и durability (надёжность). Это набор требований для транзакционных систем, которые обеспечивают надежность и целостность работы с базами данных.

Давайте разберем каждое из этих требований:

Атомарность (atomicity): Это означает, что транзакция рассматривается как неделимая и непрерываемая операция. Все изменения, внесенные в базу данных в рамках транзакции, должны быть либо успешно выполнены целиком, либо полностью отменены. Например, если вы переводите деньги со счета A на счет B, то либо операция должна быть успешно завершена, либо счет A не должен быть уменьшен и счет B не должен быть увеличен.

Согласованность (consistency): Транзакции должны обеспечивать согласованность данных в базе данных. Это означает, что только допустимые изменения могут быть внесены в базу данных. Например, если у нас есть ограничение, что поле "возраст" должно быть положительным числом, то транзакция, пытающаяся внести отрицательное значение, будет отклонена, чтобы поддержать правильную согласованность данных.

Изоляция (isolation): Транзакции должны выполняться в изолированной среде, чтобы предотвратить конфликты между параллельными транзакциями. Например, если две транзакции одновременно пытаются изменить одну и ту же строку в базе данных, изоляция гарантирует правильное выполнение обеих транзакций без возникновения ошибок или неправильных результатов.

Надёжность (durability): Это требование гарантирует, что после успешного завершения транзакции изменения остаются в базе данных даже в случае сбоев системы или перезагрузки. Данные должны сохраняться и быть доступными в будущем. Например, если вы подтвердили покупку онлайн, система должна гарантировать, что информация о вашей покупке сохранится даже в случае сбоя сервера.

🔥Провожу индивидуальные занятия по python и веб разработке (Django, DRF, Fastapi, Flask, javascript и т.д.).
Обучаю с нуля, а так же провожу консультации для мидлов и синьоров.

Пишите -  https://t.me/DJWOMS

#бд #acid
👍10🔥5❤1
👋Всем привет!

CAP-теорема - говорит о том, что в распределенных системах нельзя обеспечить одновременно все три свойства: согласованность (Consistency), доступность (Availability) и устойчивость к разделению (Partition tolerance).

Давайте разберем каждое из этих свойств:

Согласованность (Consistency): Это свойство означает, что все узлы в распределенной системе видят одинаковое состояние данных в одно и то же время. То есть, если изменения вступили в силу, они будут немедленно видны всем участникам системы. Если система обеспечивает согласованность, это означает, что данные всегда корректны и актуальны.

Доступность (Availability): Это свойство означает, что все запросы к системе должны быть успешно обработаны без задержек или отказов. Если система обеспечивает доступность, это означает, что она всегда готова отвечать на запросы пользователей.

Устойчивость к разделению (Partition tolerance): Это свойство означает, что система может продолжать функционировать даже в случае разделения сети на отдельные части. Оно гарантирует, что даже если некоторые узлы системы не могут связываться друг с другом, остальные части системы все равно должны работать независимо.

CAP-теорема утверждает, что в распределенных системах можно обеспечить только два из трех указанных свойств - либо согласованность и доступность (но теряется устойчивость к разделению), либо согласованность и устойчивость к разделению (но теряется доступность), либо доступность и устойчивость к разделению (но теряется согласованность).

Важно понимать, что выбор между этими свойствами зависит от потребностей конкретной системы. Разработчики и архитекторы должны принимать решения, какие свойства имеют наибольшую важность для конкретного приложения.


🔥Провожу индивидуальные занятия по python и веб разработке (Django, DRF, Fastapi, Flask, javascript и т.д.).
Обучаю с нуля, а так же провожу консультации для джунов, мидлов и синьоров.

Пишите -  https://t.me/DJWOMS

#cap
👍7🔥4
В Python оператор is используется для сравнения двух объектов и проверки, указывают ли они на один и тот же объект в памяти.

Синтаксис использования оператора is:

object1 is object2

Если object1 и object2 указывают на один и тот же объект в памяти, то результатом выражения будет True, иначе будет False.

Например:

a = [1, 2, 3]
b = a
c = [1, 2, 3]

print(a is b) # True, так как a и b указывают на один и тот же объект в памяти

print(a is c) # False, так как a и c указывают на разные объекты в памяти

В этом примере a и b являются двумя переменными, которые ссылаются на один и тот же список [1, 2, 3], поэтому a is b возвращает True. С другой стороны, a и c указывают на разные объекты, даже если имеют одинаковое содержимое, поэтому a is c возвращает False.

Оператор is проверяет на совпадение идентичности объектов, то есть проверяет, являются ли объекты одним и тем же объектом в памяти.

Используем оператор ==

print(a == b)
# True
print(a == c)
# True

Это связано с тем, что значения a, b, c равны, тогда условие становится истинным.

Здесь (a is c) False, потому что a и c указывают на два разных объекта, хотя их содержимое может быть одинаковым.
Итак, мы можем сказать, что is вернет True, если две переменные указывают на один и тот же объект и ==, если объекты, на которые ссылаются переменные, равны.
👍10🤔1
В продолжение прошлого поста 👆

a = 250
b = 250

print("a == b", a == b, f"\na ID: {id(a)}\nb ID: {id(b)}")
print("a is b", a is b, f"\na ID: {id(a)}\nb ID: {id(b)}")

Вывод:

a == b True 
a ID: 134702572068880
b ID: 134702572068880
a is b True
a ID: 134702572068880
b ID: 134702572068880

Поведение, которое вы наблюдаете, связано с концепцией кэширования чисел в Python.

В нашем примере, хотя переменные a и b содержат одинаковое значение 250, их адреса id также являются одинаковыми. Это связано с механизмом, называемым Integer Caching (кэширование целых чисел), который оптимизирует использование памяти для некоторых целочисленных значений в Python.

В данном случае, числа в диапазоне от -5 до 256 кэшируются и используются повторно, чтобы экономить ресурсы и снизить накладные расходы на работу с числами. Поэтому, когда вы создаете переменные a и b и присваиваете им значение 250, они ссылаются на один и тот же объект в памяти.

Это поведение может варьироваться в зависимости от версии интерпретатора Python и других факторов. Например, некоторые реализации Python могут расширять кэширование до больших значений или даже отключать его.

Важно отметить, что это особенность языка Python и не следует полагаться на сравнение адресов id для проверки равенства объектов или выполнения других операций сравнения. Вместо этого, для сравнения значений следует использовать оператор ==, а для проверки идентичности - оператор is.

При значениях более 256

a = 1000
b = 1000

print("a == b", a == b, f"\na ID: {id(a)}\nb ID: {id(b)}")
print("a is b", a is b, f"\na ID: {id(a)}\nb ID: {id(b)}")

Вывод:

a == b True 
a ID: 134702146752560
b ID: 134702146753648
a is b False
a ID: 134702146752560
b ID: 134702146753648


Еще пример:

a = "abcdf"
b = "abcdf"

print("a == b", a == b, f"\na ID: {id(a)}\nb ID: {id(b)}")
print("a is b", a is b, f"\na ID: {id(a)}\nb ID: {id(b)}")

Вывод
a == b True
a ID: 2157338698544
b ID: 2157338698544
a is b True
a ID: 2157338698544
b ID: 2157338698544

Данное поведение, связано с использованием интернирования строк в Python.

В нашем примере, когда вы создаете строки a и b с одинаковым значением "abcdf", они на самом деле ссылаются на один и тот же объект в памяти. Это связано с интернированием строковых литералов, то есть сохранением одной копии каждого уникального значения строки в памяти и использованием этой копии вместо создания новых объектов для каждого использования.

Другими словами, Python оптимизирует использование памяти, создавая только один объект со значением "abcdf" и указывая и a, и b на него.
👍14
😱В прошлом посту допустил ошибку в примере с числом 1000.
Виноват, исправил.

Теперь пример верный с числом 250 и 1000.
👌7😱4👍2
Вот я опять перебрался 😎

Жду комп и интернет, продолжу контент)
🔥24🍾3👍2