Python RU
13.4K subscribers
871 photos
41 videos
36 files
1.12K links
Все для python разработчиков

админ - @haarrp

@python_job_interview - Python собеседования

@ai_machinelearning_big_data - машинное обучение

@itchannels_telegram - 🔥лучшие ит-каналы

@programming_books_it - it книги

@pythonl

РКН: clck.ru/3Fmy2j
加入频道
Singleton (Одиночка) — порождающий шаблон проектирования, гарантирующий, что в однопроцессном приложении будет единственный экземпляр некоторого класса, и предоставляющий глобальную точку доступа к этому экземпляру.

📎 Реализация синглтона через декоратор класса:

def singleton(cls):
# храним все разные синглтоны с одном словаре (класс -> экземпляр)
instances = {}
def getinstance():
# если класса нет среди ключей нашего словаря - создадим экземпляр
if cls not in instances:
instances[cls] = cls()
# вернем ссылку на него
return instances[cls]
return getinstance


Вот так мы помечаем, что класс MySingleton – синглтон:

@singleton
class MySingleton:
def __init__(self):
self.x = 10
print("__init__")


📎 Пример (проверяем единственность экземляра):

>>> x1 = MySingleton()
init
>>> x2 = MySingleton()
>>> x1 is x2
True
>>> x1.x = 100
>>> x2.x
100

init было вызвано единажды
• Обе переменные указывают на один экземпляр
• При изменении полей в одном экземпляре, они меняются и во втором.

Плохо то, что MySingleton здесь – это функция (результат работы декоратора), а не класс: вы не можете вызывать класс-методы у нее. Эта проблема решается использованием метаклассов.

# обратите внимание, метакласс наследован от type
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]

Прим
енение (Python 3):

class MySingleton(metaclass=Singleton):
def __init__(self):
self.x = 10
print("__init__")

⚠️ Не злоупотребляйте синглтонами, они осложняют тестирование кода.

@pro_python_code
🔥 CompressedCrack Python скрипт для подбора паролей к zip и rar архивам.

CompressedCrack - простой и эффективный скрипт для подбора паролей к zip и rar архивам.

Установка:
$ git clone https://github.com/thanhminh6996/CompressedCrack.git

$ cd ./CompressedCrack

Использование:
Нас интересует скрипт crack.py который принимает несколько параметров:

$ python crack.py -i file_name min_character max_character characters

🌵 -i file_name : путь до архива.
🌵 min_character: минимальное количество символов в пароле.
🌵 max_character: максимальное количество символов в пароле.
🌵 characters: используемые в пароле символы по которым будет осуществляться перебор, 123qwerty!@$ и т.д.

$ python crack.py -i file.zip 1 5 1234567890

⚙️ GitHub/Инструкция

@pro_python_code
Каким будет результат выполнения кода?
Anonymous Quiz
6%
2*34+23+3
11%
2*34 + 23 + 3
2%
243
58%
666
2%
None
7%
Error
14%
Узнать ответ
🌟 Малоизвестная фишка генератора

Если функция принимает единственный аргумент, то можно в нее передать генераторное выражение без скобок:

>>> sum(x * x for x in range(5))
30

Тоже самое, что и:

>>> sum((x * x for x in range(5)))
30


Но вне вызова функции генератор недопустимо использовать без скобок – это синтаксическая ошибка:

>>> g = x * x for x in range(5)
File "<stdin>", line 1
g = x * x for x in range(5)
^
SyntaxError: invalid syntax


@pro_python_code
numpy.meshgrid(): How Does It Work? When Do You Need It? Are There Better Alternatives?

https://thepythoncodingbook.com/2022/05/28/numpy-meshgrid/
Что выведет код?
Anonymous Quiz
12%
1
27%
-2
8%
0
53%
Ошибку
Магические методы и пустые списки

Методы с двойным подчеркиванием в начале и в конце, например, __eq__, __hash__, __init__, в Python называют магическими методами. Их назвали так, потому что они добавляют магию в поведение класса.

Например, метод __init__ неявно вызывается при инициализации объекта:

Foo:
def __init__(self, a, b):
self.a = a
self.b = b

foo = Foo(7, 9) # вызывается __init__

print(foo.a, foo.b) # 7, 9

Но сегодня я хочу поговорить о магичесом методе __bool__. В тех классах, где этот метод определен, он сообщает интерпретатору, как оценить булево значение произвольного объекта.

Зачем нам это? Это нестареющая классика: чтобы проверить, словарь или список на непустоту, начинающие часто используют стиль как в C++:

if len(a) != 0:
pass

В то время как PEP8 рекомендует делать просто:

if not a:
pass

И это работает ровно потому, что в момент if a: вызывается метод __bool__ класса список.

Для пользовательских объектов, где __bool__ не перегружен, по умолчанию возвращается True.

if foo:
print(True)
else:
print(False)

# True

Но если добавить

Foo:
def __init__(self, a, b):
self.a = a
self.b = b

def __bool__(self):
return False

То поведение изменится:

if foo:
print(True)
else:
print(False)

# False

Кстати, в случае, если метода __bool__ в классе нет, то интерпретатор будет искать метод __len__ (длина). Поведение такое же: если __len__ возвращает 0, то логическое значение оценивается как False.

Что с этим делать? Помнить, что falsy (значения, которые оцениваются как False) в Python это:

🐙 пустые словари {},
🐙 списки [],
🐙 кортежи (),
🐙 множества set(),
🐙 строки "",
🐙 пустые range(0),
🐙 нули любого численного типа: 0, 0.0, 0j
🐙 константы None и собственно False

А truthy значения это:

🐙 любые пользовательские объекты по умолчанию
🐙 непустые словари, множества, строки, списки, ...
🐙 константа True

И писать проверку на непустоту красиво:

not a:
pass

#magic #dunder #bool

@pro_python_code
Вывод строки или списка n раз

Можно использовать умножение (*) со строками или списками; умножать их можно любое количество раз.

Интересным вариантом может быть определение списка с постоянным значением, скажем, ноль.
This media is not supported in your browser
VIEW IN TELEGRAM
🎮 Пишем игру - симуляция жизни на Python

Код

@pro_python_code
Проверяем, существует ли значение в словаре Python.

https://www.pythonforbeginners.com/basics/check-if-value-exists-in-a-dictionary-in-python

@pro_python_code
3️⃣ трюка с itertools в Python

Читать

@pro_python_code
Несколько возможных типов возвращаемых значений 

Если в вашей функции есть переменная, принимающая значения различных типов, можно использовать типы typing.Optional или typing.Union.

Используйте Optional, если значение будет либо определенного типа, либо исключительно None.
🕘 schedule в Python

Вам приходилось работать с CRON? Это такой сервис в nix-системах, который позволяет регулярно в определенные моменты времени запускать скрипты или программы. Штука с долгой историей, в наследство которой достался странный синтаксиc для описания правил:

0 * * * * my_script

Что если бы мы хотели иметь свой CRON внутри программы Python, чтобы в нужные моменты времени вызывать функции? Да еще, чтобы у него был человеческий синтаксис? Такая библиотека есть и называется schedule.

pip install schedule

Рассмотрим пример:

import schedule
import time

def job():
print("Работаю")

schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).minutes.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
schedule.every().minute.at(":17").do(job)

# нужно иметь свой цикл для запуска планировщика с периодом в 1 секунду:
while True:
schedule.run_pending()
time.sleep(1)


Как видите, правила для задания временных интервалов прекрасно читаются, словно они предложения на английском языке. Перевод пары примеров:

# спланируй.каждые(10).минут.сделать(работу)
schedule.every(10).minutes.do(job)

# спланируй.каждый().день.в(10:30).сделать(работу)
schedule.every().day.at("10:30").do(job)


В задания можно передавать параметры вот так:

def greet(name):
print('Hello', name)
schedule.every(2).seconds.do(greet, name='Alice')


Если по какой-то причине нужно отменить задание, это делается так:

def job1():
# возвращаем такой токен, и это задание снимается с выполниния в будущем
return schedule.CancelJob
schedule.every().day.at('22:30').do(job1)

Если нужно отменить группу заданий, то к ним добавляют тэги:

schedule.every().day.do(greet, 'Monica').tag('daily-tasks')
schedule.every().day.do(greet, 'Derek').tag('daily-tasks')

schedule.clear('daily-tasks') # массовая отмена по тэгу

Метод to позволяет задать случайный интервал для выполнения задания, например от 5 до 10 секунд:

schedule.every(5).to(10).seconds.do(my_job)

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

Если задания занимают продолжительное время или должны выполняться параллельно, то вам самостоятельно придется организовать их выполнение в отдельных потоках. Примеры есть в официальном FAQ.
ManimPython движок, который позволяет создавать интересные математические анимации

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

Примеры использования данного движка (Рекомендую просмотреть)

@pro_python_code
This media is not supported in your browser
VIEW IN TELEGRAM
📊 Alive-progress on Python

letters = [chr(ord('A') + x) for x in range(26)]
with alive_bar(26, dual_line=True, title='Alphabet') as bar:
for c in letters:
bar.text = f'-> Teaching the letter: {c}, please wait...'
if c in 'HKWZ':
print(f'fail "{c}", retry later')
time.sleep(0.3)
bar()


Alphabet |
███████████████████████████▊ | ▃▅▇ 18/26 [69%] in 6s (3.2/s, eta: 3s)
-> Teaching the letter: S, please wait...


Git: https://github.com/rsalmei/alive-progress