КулЛиб - Классная библиотека! Скачать книги бесплатно
Всего книг - 716641 томов
Объем библиотеки - 1426 Гб.
Всего авторов - 275494
Пользователей - 125281

Последние комментарии

Новое на форуме

Новое в блогах

Впечатления

yan.litt про серию За последним порогом

В целом средненько, я бы даже сказал скучная жвачка. ГГ отпрыск изгнанной мамки-целицельницы, у которого осталось куча влиятельных дедушек бабушек из великих семей. И вот он там и крутится вертится - зарабатывает себе репу среди дворянства. Особого негатива к нему нет. Сюжет логичен, мир проработан, герои выглядят живыми. Но тем не менее скучненько как то. Из 10 я бы поставил 5 баллов и рекомендовал почитать что то более энергичное.

Рейтинг: 0 ( 0 за, 0 против).
Lena Stol про Небокрад: Костоправ. Книга 1 (Героическая фантастика)

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

Рейтинг: 0 ( 1 за, 1 против).
Lena Stol про Батаев: Проклятьем заклейменный (Героическая фантастика)

Бросила читать практически в самом начале - неинтересно.

Рейтинг: 0 ( 1 за, 1 против).
Lena Stol про Чернов: Стиратель (Попаданцы)

Хорошее фэнтези, прочитала быстро и с интересом.

Рейтинг: 0 ( 1 за, 1 против).
Влад и мир про серию История Московских Кланов

Прочитал первую книгу и часть второй. Скукота, для меня ничего интересно. 90% текста - разбор интриг, написанных по детски. ГГ практически ничему не учится и непонятно, что хочет, так как вовсе не человек, а высший демон, всё что надо достаёт по "щучьему велению". Я лично вообще не понимаю, зачем высшему демону нужны люди и зачем им открывать свои тайны. Живётся ему лучше в нечеловеческом мире. С этой точки зрения весь сюжет - туповат от

  подробнее ...

Рейтинг: 0 ( 0 за, 0 против).

Типизированный Python для профессиональной разработки [Алексей Голобурдин] (pdf) читать постранично, страница - 16

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

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

from datetime import datetime
from dataclasses import dataclass
@dataclass
class User:
birthday: datetime
users = (

# сменили на tuple

User(birthday=datetime.fromisoformat("1988-01-01")),
User(birthday=datetime.fromisoformat("1985-07-29")),
User(birthday=datetime.fromisoformat("2000-10-10"))
)
def get_younger_user(users: list[User]) -> User:
"""Возвращает самого молодого пользователя из списка"""
sorded_users = sorted(users, key=lambda x: x.birthday)
return sorded_users[0]

print(get_younger_user(users))

# тут видна ошибка в pyright!

Код работает (повторимся, что интерпретатор не проверяет типы в type hinting), но
проверка типов в редакторе (и mypy) ругается, это нехорошо.
Если мы посмотрим документацию по функции sorted, то увидим, что первый
элемент там назван iterable, то есть итерируемый, то, по чему можно
проитерироваться. То есть мы можем передать любую итерируемую структуру:

from typing import Iterable
def get_younger_user(users: Iterable[User]) -> User | None:
if not users: return None
sorded_users = sorted(users, key=lambda x: x.birthday)
return sorded_users[0]

И теперь всё в порядке. Мы можем передать любую итерируемую структуру,
элементами которой являются экземпляры User.
А если нам надо обращаться внутри функции по индексу к элементам
последовательности? Подойдёт ли Iterable? Нет, так как Iterable подразумевает
возможность итерироваться по контейнеру, то есть обходить его в цикле, но это не
предполагает обязательной возможности обращаться по индексу. Для этого есть
Sequence:
from typing import Sequence
def get_younger_user(users: Sequence[User]) -> User | None:
"""Возвращает самого молодого пользователя из списка"""
if not users: return None
print(users[0])
sorded_users = sorted(users, key=lambda x: x.birthday)
return sorded_users[0]

Теперь всё в порядке. В Sequence можно обращаться к элементам по индексу.
Ещё один важный вопрос тут. А зачем использовать Iterable или Sequence, если
можно просто перечислить разные типы контейнеров? Ну их же ограниченное
количество — там list, tuple, set, dict. Для чего нам тогда общие типы Iterable и
Sequence?

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

from typing import Sequence
class Users:
def __init__(self, users: Sequence[User]):
self._users = users
def __getitem__(self, key: int) -> User:
return self._users[key]
users = Users((

# сменили на tuple

User(birthday=datetime.fromisoformat("1988-01-01")),
User(birthday=datetime.fromisoformat("1985-07-29")),
User(birthday=datetime.fromisoformat("2000-10-10"))
))
for u in users:
print(u)

Способов создать такую структуру, по которой можно итерироваться или
обращаться по индексам, в Python много, это один из способов. Важно просто
понимать, что если вам надо показать структуру, по которой, например, можно
итерироваться, то не стоит ограничивать набор таких структур простым
перечислением списка, кортежа и чего-то ещё. Используйте обобщённые типы,
созданные специально для этого, например, Iterable или Sequence, потому что они
покроют действительно всё, в том числе и свои кастомные (самописные)
реализации контейнеров.
Ну и напоследок — как определить тип словаря, ключами которого являются строки,
а значениями, например, объекты типа User:
some_users_dict: dict[str, User] = {
"alex": User(birthday=datetime.fromisoformat("1990-01-01")),
"petr": User(birthday=datetime.fromisoformat("1988-10-23"))
}

И также, если нет смысла ограничиваться именно словарём и подойдёт любая
структура, к которой можно обращаться по ключам — то есть обобщённый тип
Mapping:

from typing import Mapping
def smth(some_users: Mapping[str, User]) -> None:
print(some_users["alex"])
smth({
"alex": User(birthday=datetime.fromisoformat("1990-01-01")),
"petr": User(birthday=datetime.fromisoformat("1988-10-23"))
})

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

three_ints = tuple[int, int, int]

Если количество элементов неизвестно — можно так:
tuple_ints = tuple[int, ...]

Дженерики
Что если мы хотим написать обобщённую функцию, которая принимает на вход
итерируемую структуру, то есть структуру, по которой можно итерироваться, и
возвращает результат первой итерации?

from typing import TypeVar, Iterable
T = TypeVar("T")
def first(iterable: Iterable[T]) -> T | None:
for element in iterable:
return element
print(first(["one", "two"])) # one
print(first((100, 200))) # 200

Как видите, типом данных в этой итерируемой структуре iterable могут быть любые
данные, а наши type hinting в функции first говорят буквально, что функция

принимает на вход итерабельную структуру данных, каждый элемент которой имеет
тип T, и функция возвращает тот же тип T. Тип T при этом может быть любым.
Это так называемые дженерики, то есть обобщённые типы.
Причём имя T здесь это пример, он часто используется именно так, T, от Type, но
название типа может быть и любым