🐍 Укус питона 🐍 - это канал, посвященный программированию на языке Python. Здесь вы найдете тематические уроки, лайфхаки и много полезной информации для всех, кто интересуется этим языком программирования. Администратор канала - @it_dashka, который делится своими знаниями и опытом в этой области. Если вы хотите купить рекламу или узнать больше о канале, вы можете посетить ссылку: https://telega.in/c/byteofpython. Также у нас есть чат, где вы можете общаться с другими участниками и делиться своими успехами и вопросами - @abyteofpython. Присоединяйтесь к нам, узнавайте новое и развивайтесь вместе с нами! 🐍👽🔊👉
11 Feb, 07:00
enumerate()
в Python?enumerate()
добавляет индекс при итерации по списку.fruits = ["🍎", "🍌", "🍇"]
for i, fruit in enumerate(fruits, start=1):
print(i, fruit)
1 🍎
2 🍌
3 🍇
•
Упрощает работу с индексами в циклах•
Делает код читаемым без range(len())
enumerate()
вместо range(len())
для чистого и Pythonic-кода! 10 Feb, 15:00
slots
в Python и зачем он нужен?slots
ограничивает список атрибутов у экземпляров класса, экономя память за счет отказа от dict
.slots
:class Person:
def init(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 25)
p.city = "New York" # Можно добавить новый атрибут
slots
:class Person:
slots = ("name", "age") # Разрешены только эти атрибуты
def init(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 25)
p.city = "New York" # ❌ AttributeError: 'Person' object has no attribute 'city'
slots
•
Экономит память (не создается dict
) •
Ускоряет доступ к атрибутам •
Предотвращает создание лишних атрибутовslots
, если нужно много однотипных объектов и важна производительность! 09 Feb, 09:00
@property
в Python?@property
превращает метод класса в свойство, позволяя обращаться к нему без скобок.class Person:
def init(self, name):
self._name = name
@property
def name(self):
return self._name
p = Person("Alice")
print(p.name) # Alice (как атрибут, но с логикой)
•
Позволяет использовать методы как атрибуты•
Защищает данные от прямого изменения•
Позволяет добавить логику без изменения интерфейса@property
делает код чище и безопаснее, улучшая инкапсуляцию! 08 Feb, 09:00
set
в Python не всегда такой хаотичный, как кажется? Разбираемся, как множества устроены под капотом, как работают хэш-таблицы и почему порядок элементов иногда оказывается предсказуемым. 07 Feb, 15:00
lambda
— это анонимная функция, которая записывается в одну строку и не требует def
. Используется там, где нужна простая операция без имени функции.def square(x):
return x ** 2
square_lambda = lambda x: x ** 2
print(square(5)) # 25
print(square_lambda(5)) # 25
map()
— Применение функции к спискуnums = [1, 2, 3, 4]
squared = list(map(lambda x: x ** 2, nums))
print(squared) # [1, 4, 9, 16]
filter()
— Фильтрация данныхeven = list(filter(lambda x: x % 2 == 0, nums))
print(even) # [2, 4]
sorted()
— Сортировка по ключуpairs = [(1, 'one'), (3, 'three'), (2, 'two')]
pairs.sort(key=lambda x: x[0])
print(pairs) # [(1, 'one'), (2, 'two'), (3, 'three')]
lambda
?•
Когда функция простая и короткая•
Когда она нужна один разlambda
, если логика сложная – лучше писать def
. 06 Feb, 07:00
is
и ==
в Python==
(равенство) проверяет, равны ли значения объектов:a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (значения одинаковые)
is
(идентичность) проверяет, указывают ли переменные на один и тот же объект в памяти:print(a is b) # False (разные объекты)
int
, str
, tuple
) Python кеширует значения:x = 256
y = 256
print(x is y) # True (указывают на один объект)
==
для сравнения значений и is
для проверки, ссылаются ли переменные на один объект в памяти! 05 Feb, 15:00
*args
и **kwargs
в Python*args
— передает позиционные аргументы как кортеж:def add_numbers(*args):
return sum(args)
print(add_numbers(1, 2, 3)) # 6
**kwargs
— передает именованные аргументы как словарь:def greet(**kwargs):
print(kwargs)
greet(name="Alice", age=25) # {'name': 'Alice', 'age': 25}
*args
для списка значений и **kwargs
для гибких параметров! 04 Feb, 07:00
int
, float
, str
, tuple
, frozenset
x = "hello"
x += " world" # Создается новый объект, а не изменяется старый
list
, dict
, set
, bytearray
lst = [1, 2, 3]
lst.append(4) # Список изменяется в той же области памяти
def modify_list(lst):
lst.append(99) # Изменяет оригинальный список!
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # [1, 2, 3, 99]
•
Используйте tuple
, если данные не должны изменяться.•
Будьте осторожны с изменяемыми объектами при передаче в функции.•
Если нужно копирование, используйте .copy()
или deepcopy()
. 03 Feb, 15:00
•
В CPU-интенсивных задачах (например, обработка данных, вычисления) многопоточность не дает прироста производительности.•
В I/O-интенсивных задачах (сетевые запросы, работа с файлами) GIL почти не влияет, так как потоки могут освобождать блокировку во время ожидания операций ввода-вывода.multiprocessing
), которая запускает отдельные процессы без GIL, или попробуйте альтернативные реализации Python, такие как Jython или PyPy. 02 Feb, 09:00
yield
в Python?yield
используется для создания генераторов, которые возвращают данные по мере запроса, вместо хранения всего результата в памяти.def count_up_to(n):
count = 1
while count <= n:
yield count # Возвращает значение и приостанавливает выполнение
count += 1
for num in count_up_to(5):
print(num)
yield
позволяет приостанавливать и возобновлять выполнение функции, экономя память и упрощая работу с потоками данных. 15 Jan, 13:00
03 Jan, 07:00
import typer
app = typer.Typer()
@app.command()
def hello(name: str):
"""
Простое приветствие.
"""
print(f"Привет, {name}!")
@app.command()
def goodbye(name: str, formal: bool = False):
"""
Прощание. Можно сделать формальным.
"""
if formal:
print(f"До свидания, {name}!")
else:
print(f"Пока, {name}!")
if name == "main":
app()
19 Dec, 11:51
15 Dec, 09:00
class DatabaseConnection:
def init(self, db_name):
self.db_name = db_name
def enter(self):
# Действия при входе в контекст
print(f"Connecting to database '{self.db_name}'...")
self.connection = f"Connection to {self.db_name}"
return self.connection # Возвращаем объект соединения
def exit(self, exc_type, exc_val, exc_tb):
# Действия при выходе из контекста (закрытие соединения)
print(f"Closing connection to '{self.db_name}'...")
self.connection = None
return False # Если возникло исключение, не подавлять его
# Использование менеджера контекста
with DatabaseConnection('test_db') as conn:
print(f"Using {conn} to execute queries...")
Connecting to database 'test_db'...
Using Connection to test_db to execute queries...
Closing connection to 'test_db'...
30 Nov, 09:00
import importlib
# Динамический импорт модуля
math = importlib.import_module('math')
# Использование импортированного модуля
print(math.pi) # Выводит 3.141592653589793
# Перезагрузка модуля
importlib.reload(math)
27 Nov, 15:00
import jmespath
jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
# output: 'baz'
jmespath.search('foo.*.name', {'foo': {'bar': {'name': 'one'}, 'baz':
{'name': 'two'}}})
# output: ['one', 'two']
24 Nov, 09:04
python manage.py migrate
, которая применит все необходимые изменения к базе данных. При этом Django будет автоматически отслеживать и применять новые миграции при изменениях в моделях.python manage.py makemigrations --empty
, чтобы определить свои собственные изменения в базе данных. 21 Nov, 16:00
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age'])
person1 = Person(name='John', age=30)
person2 = Person(name='Jane', age=25)
print(person1.name) # John
print(person2.age) # 25
20 Nov, 08:59
17 Nov, 09:00
double
, которая удваивает переданное число:def double(number):
return number * 2
my_list = []
def add_to_list(value):
my_list.append(value)
14 Nov, 15:00
{
'🔥': "5104841245755180586",
'👍': "5107584321108051014",
'👎': "5104858069142078462",
'❤️': "5044134455711629726",
'🎉': "5046509860389126442",
'💩': "5046589136895476101"
}
10 Nov, 09:00
import timeit
print(timeit.timeit('"-".join(str(n) for n in range(100))', number=10000))
"-".join(str(n) for n in range(100))
10 000 раз и выведет затраченное на это время.import timeit
def my_function():
return "-".join(str(n) for n in range(100))
print(timeit.timeit(my_function, number=10000))
08 Nov, 15:00
isinstance()
и issubclass()
для определения отношения наследования между классами.class A:
def init(self, value):
self.value = value
class B:
def init(self, value):
self.value = value
def subclasshook(cls, subclass):
return (hasattr(subclass, 'value') and
callable(subclass.value) and
subclacc.value.name == 'print_value')
class C:
def init(self, value):
self.value = value
def print_value(self):
print(self.value)
a = A(5)
b = B(10)
c = C(15)
# Проверка
print(issubclass(C, B)) # True
print(issubclass(A, B)) # False
subclasshook
класса B
проверяет, есть ли у подкласса метод print_value
. Если да, то возвращает True
, что позволяет считать его подклассом B
. 06 Nov, 09:21
03 Nov, 09:00
iter()
и next()
. Метод iter()
возвращает сам итератор, а next()
— следующий элемент коллекции. Если элементы заканчиваются, next()
должен вызвать исключение StopIteration
. Итераторы позволяют явно перебирать элементы коллекции, не требуя, чтобы все элементы были доступны в памяти одновременно.yield
. Главное отличие генератора заключается в том, что значения генерируются по требованию. Каждый раз, когда генератор достигает yield
, он возвращает значение и «замирает», сохраняя своё состояние до следующего вызова. Это позволяет использовать меньше памяти при итерации по длинным последовательностям. 01 Nov, 15:00
count(start, step)
: Генерирует бесконечную арифметическую прогрессию, начиная с start, с шагом step.cycle(iterable)
: Бесконечно повторяет элементы из iterable.chain(*iterables)
: Объединяет несколько итерируемых объектов в один последовательный поток.zip_longest(*iterables, fillvalue=None)
:import itertools
# Создаем бесконечную последовательность с шагом 2
counter = itertools.count(start=10, step=2)
for _ in range(5):
print(next(counter)) # Выведет числа: 10, 12, 14, 16, 18
# Объединяем несколько списков в один последовательный поток
letters = ['a', 'b', 'c']
numbers = [1, 2, 3]
combined = itertools.chain(letters, numbers)
print(list(combined)) # Выведет: ['a', 'b', 'c', 1, 2, 3]
30 Oct, 15:26
27 Oct, 12:15
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'product_table'
ordering = ['-created_at']
24 Oct, 11:01
23 Oct, 07:00
20 Oct, 09:00
iter()
и next()
. Метод iter()
возвращает сам итератор, а next()
— следующий элемент коллекции. Если элементы заканчиваются, next()
должен вызвать исключение StopIteration
. Итераторы позволяют явно перебирать элементы коллекции, не требуя, чтобы все элементы были доступны в памяти одновременно.yield
. Главное отличие генератора заключается в том, что значения генерируются по требованию. Каждый раз, когда генератор достигает yield
, он возвращает значение и «замирает», сохраняя своё состояние до следующего вызова. Это позволяет использовать меньше памяти при итерации по длинным последовательностям. 19 Oct, 09:58
help(print)
Это приведет к выводу документации о функции print в вашем интерпретаторе Python.
17 Oct, 15:00
@login_manager.user_loader
. Эта функция должна принимать идентификатор пользователя в качестве параметра и возвращать объект пользователя.@login_required
, который применяется к функции представления и автоматически проверяет статус аутентификации пользователя перед выполнением функции. 13 Oct, 09:00
getattr
class Missing:
attr = 42
def getattr(self, name):
print(f"In getattr, asked for {name}")
return 73
m = Missing()
print(m.attr) # 42
print(m.xyz) # In getattr, asked for xyz; 73
getattribute
class Always:
attr = 42
def getattribute(self, name):
print(f"In getattribute, asked for {name}")
return 73
a = Always()
print(a.attr) # In getattribute, asked for attr; 73
print(a.xyz) # In getattribute, asked for xyz; 73
getattribute
— это метод, который управляет всеми запросами атрибутов, тогда как getattr
вызывается, когда getattribute
не находит атрибут. 11 Oct, 07:00
import time
start_time = time.time()
# Код, скорость выполнения которого вы хотите измерить
for i in range(0, 10000):
pass
end_time = time.time()
execution_time = end_time - start_time
print(f"Время выполнения: {execution_time} секунд")