Сам себе декоратор сколько уровней
САМЫЕ ЛУЧШИЕ ФЛЕШ ИГРЫ
ПОИСК
КАТЕГОРИИ ИГР
- Angry birds (35)
- games (1)
- Автобусы (51)
- Азартные (6)
- Аниме (54)
- Арканойды (7)
- Барашек Шон (18)
- Барби (83)
- Барбоскины (19)
- Блоки (36)
- Больница (60)
- Бродилки (183)
- Вертолеты (31)
- Время приключений (39)
- Вселенная Стивена (14)
- Гонки (96)
- Готовим еду (89)
- Гравити Фолз (11)
- Грузовики (50)
- ГТА (54)
- Губка Боб (83)
- Гуппи и пузырики (11)
- Дальнобойщики (17)
- Даша (14)
- Дизайн (78)
- Динозавры (84)
- Для девочек (252)
- Для мальчиков (95)
- Дом (43)
- Домино (28)
- Драки (75)
- Единороги (39)
- Железный человек (11)
- Зверополис (17)
- Злая бабушка (18)
- Змейка (42)
- Зума (36)
- Игры выживание (54)
- ИГРЫ ДЛЯ СМАРТФОНОВ (47)
- Игры Зомби (96)
- Игры Лего (78)
- Игры Машины (571)
- Игры на двоих (96)
- Игры на ловкость (229)
- Игры Новый год (85)
- Игры Тесты (96)
- Кейворды (3)
- Кликеры (71)
- Корабли (36)
- Королевская битва (37)
- Космос (96)
- Кошки (145)
- Красный шар (29)
- Крестики-нолики (56)
- Кроссворды (13)
- Кубики (35)
- Кунфу Панда (9)
- Кухня (83)
- Линии (30)
- Логические (130)
- Лото (14)
- Лунтик (25)
- Магазин (51)
- Маджонги (114)
- Майнкрафт (96)
- Малышка Хайзел (18)
- Маникюр (40)
- Марио (57)
- Математические игры (39)
- Маша и медведь (36)
- Микки Маус (23)
- Морской бой (19)
- Мотоциклы (96)
- Мстители (26)
- Найди конфету (10)
- Нарды (17)
- Одевалки (96)
- Пазлы (91)
- Парикмахерская (84)
- Пасьянсы (108)
- Пираты (48)
- Погрузчик (7)
- Поезда (25)
- Поиск предметов (37)
- Покемоны (15)
- Полиция (39)
- Принцессы (191)
- Пузыри (56)
- Рапунцель (52)
- Раскраски (78)
- Рисовалки (51)
- Робокар Поли (9)
- Роботы (40)
- Рыбалка (35)
- Рыбки (54)
- Самолеты (50)
- Сапер (38)
- Свинка Пеппа (19)
- Симуляторы (88)
- Сканворды (50)
- Скуби Ду (30)
- Слова (27)
- Смешарики (34)
- Собаки (52)
- Спортивные (239)
- Стикмен (96)
- Стратегии (58)
- Стрелялки (224)
- Судоку (65)
- Тамагочи (96)
- Танчики (172)
- Тетрис (43)
- Том и Джерри (50)
- Тракторы (16)
- Трансформеры (20)
- Три в ряд (76)
- Тролли (15)
- Уборка (57)
- Улитка Боб (8)
- Ферма (54)
- Фиксики (38)
- Финес и Ферб (14)
- Флеш игры (39)
- Холодное сердце (96)
- Человек-паук (38)
- Черепашки-нинзя (56)
- Шарики (113)
- Шахматы (33)
- Шашки (28)
- Шрек (13)
- Щенячий патруль (42)
- Эвер Афтер Хай (22)
- Эйви (4)
Игра Сам себе Декоратор
«Сам себе Декоратор» — это новая захватывающая игра в жанре «Три в Ряд», в которой вам предстоит восстанавливать полуразрушенные заброшенные помещения для создания уютного кафе, цветочного магазина и многих других локаций! Зарабатывайте звезды за успешное прохождение красочных уровней и постепенно обустраивайте дизайн будущей кофейни, чтобы в день её открытия привлечь как можно больше посетителей! Впереди вас ждут сотни увлекательных головоломок, колоритных персонажей и забавных диалогов, благодаря которым вы сможете узнать много чего интересного!
Как играть?
Соберите в ряд 3 фишки одинакового цвета, меняя местами соседние ячейки. В каждом уровне вам нужно выполнить определенное задание, которое будет отображаться на панели слева. Помните, что у вас будет ограниченное количество ходов, поэтому тщательно продумывайте каждое свое действие. Для начала уберите всю старую мебель и поставьте вместо неё новую барную стойку, стулья, столы и другие необходимые вещи. Заштукатурьте стены и положите паркет, чтобы сделать внешний вид комнаты более привлекательным. Активируйте фейерверки, бомбы, динамит и другие вспомогательные бонусы, чтобы заработать дополнительные очки. Если у вас возникнут трудности, воспользуйтесь всплывающими подсказками на экране. Желаем удачи и приятной игры!
Дизайнер-декоратор: обзор профессии, как им стать
Чем занимается? Дизайнер-декоратор – интересная профессия, объединяющая в себе сразу два направления: дизайн и декор. Как правило, такие специалисты работают с интерьерами помещений: разрабатывают основную концепцию дизайна, его функциональную часть, прорабатывают детали.
Как стать? Чтобы освоить профессию дизайнера-декоратора, необходимо выбрать один из двух возможных вариантов обучения: поступить в ВУЗ либо найти профессиональные курсы подготовки специалистов.
В статье рассказывается:
- Отличия дизайнера от декоратора
- Плюсы и минусы профессии дизайнер-декоратор
- Обязанности, личные качества и профессиональные навыки дизайнера-декоратора
- Задачи дизайнера-декоратора
- Основные инструменты для работы дизайнера-декоратора
- Варианты обучения на дизайнера-декоратора
- Зарплата и поиск вакансий дизайнера-декоратора
- Первая работа и карьерный рост дизайнера-декоратора
- Заключительные советы для новичков
Пройди тест и узнай, какая сфера тебе подходит:
айти, дизайн или маркетинг.
Бесплатно от Geekbrains
Отличия дизайнера от декоратора
Каждый человек, даже если он не имеет отношения к сфере строительства и дизайна, понимает разницу между архитектором и дизайнером, но мало кто знает, чем отличается дизайнер от декоратора.
Что делает дизайнер:
- Решает, какой стиль лучше вписывается в квартиру или дом. Он знает, что лофт не подходит для маленькой квартиры с низкими потолками и небольшим окнами, а минимализм не применим для помещения, в котором есть эркеры и колонны.
- Подбирает цветовое решение для стен, пола и потолка, учитывая большое количество факторов.
- Разрабатывает дизайн-проект. При этом специалист занимается не только расположением мебели и осветительных приборов, но и разрабатывает планы коммуникаций – проводки, канализации, водопровода, вентиляции.
- Делает 3D-визуализацию проекта. Это помогает заказчику наглядно увидеть, как в результате будет выглядеть интерьер его жилья.
- Подбирает необходимые изделия – от мебели до ручек и гвоздей. Контролирует, чтобы ничего не выбивалось из заданного стиля и не превышало выделенный бюджет.
- Ведёт контроль рабочих процессов, чтобы всё соответствовало разработанному проекту.
Декоратор занимается следующим:
- Предлагает варианты декорирования пространства, разбавления цветовой гаммы с помощью ярких акцентов, подбирает фактуры и их сочетания. Создаёт макеты для наглядности.
- Занимается подбором мебели, текстиля, осветительных приборов, предметов искусства, керамики и фарфора. Помимо этого, он продумывает даже самые мелкие детали, благодаря которым получается особенная атмосфера в доме: выбирает зажимы для штор, кашпо для растений и дверные ручки.
- Если нужной вещи не существует, он разрабатывает эскизы, чтобы её сделали на заказ. Например, кованые изделия, витражи, вязаные или текстильные предметы.
Узнай, какие ИТ — профессии
входят в ТОП-30 с доходом
от 210 000 ₽/мес
Павел Симонов
Исполнительный директор Geekbrains
Команда GeekBrains совместно с международными специалистами по развитию карьеры подготовили материалы, которые помогут вам начать путь к профессии мечты.
Подборка содержит только самые востребованные и высокооплачиваемые специальности и направления в IT-сфере. 86% наших учеников с помощью данных материалов определились с карьерной целью на ближайшее будущее!
Скачивайте и используйте уже сегодня:

Павел Симонов
Исполнительный директор Geekbrains
Топ-30 самых востребованных и высокооплачиваемых профессий 2023
Поможет разобраться в актуальной ситуации на рынке труда
Подборка 50+ бесплатных нейросетей для упрощения работы и увеличения заработка
Только проверенные нейросети с доступом из России и свободным использованием
ТОП-100 площадок для поиска работы от GeekBrains
Список проверенных ресурсов реальных вакансий с доходом от 210 000 ₽
Получить подборку бесплатно
Уже скачали 23685
Эти специалисты не так уж сильно отличаются друг от друга: им необходимо иметь чёткое представление о стилях интерьера, художественный вкус, они должны уметь делать зарисовки и презентации для лучшего объяснения своих идей. Однако, обязанности декоратора немного уже, чем у дизайнера: первый занимается только отделочными материалами и украшением интерьера, в то время как дизайнер отвечает не только за отделку, но и за коммуникации, а также конструктивные элементы помещения.
Необязательно выбирать между этими двумя специальностями, ведь существует профессия дизайнер-декоратор. Этот человек занимается вопросами из обеих сфер. Так он один решает практически все задачи по обустройству интерьера. К тому же найти работу такому специалисту легче, и заработная плата выше.
Если вам надо сделать капитальный ремонт или вы хотите полностью изменить облик своего жилья (поменять планировку, расположение коммуникаций), значит вам нужен дизайнер.
Когда работа дизайнера будет окончена, желательно найти ещё декоратора, который поставит точку в создании красивого интерьера. Также обратиться к декоратору разумно, если вы не собираетесь делать капитальный ремонт, а просто хотите изменить цветовую гамму, добавить декор, поставить новую мебель и т.д.
Стоит понимать, что дизайнер вполне способен взять на себя роль декоратора, а вот наоборот быть не может. Оба этих специалиста имеют художественное образование, однако, техническими знаниями обладает только дизайнер интерьера.
Плюсы и минусы профессии дизайнер-декоратор
Разберёмся с плюсами и минусами специальности дизайнер-декоратор.
| Плюсы | Минусы |
| Свободный график работы. |
Большой спрос, потому что люди намного чаще стали обращаться за помощью с обустройством жилища к профессионалам.
Полученные навыки и знания могут использоваться в личных целях.
В этой профессии лучше всего себя чувствует творческая личность, потому что есть большой простор для самореализации.
Эта профессия подразумевает большое количество общения, поэтому очень важно уметь находить общий язык с другими людьми.
Обязанности, личные качества и профессиональные навыки дизайнера-декоратора
В этой профессии необходимо иметь знания из различных сфер. Творческих способностей недостаточно – надо ещё развивать организаторские навыки. Дизайнер-декоратор занимается не только разработкой проектов, но и контактирует с клиентами, подрядчиками, рабочими, в ходе авторского надзора.
Что входит в обязанности данного специалиста:
- изучение пожеланий клиента, предложение собственных идей;
- создание технических планов с замерами и эскизами (при этом необходимо опираться на строительные нормы и правила (СНИП));
- разработка макетов;
- расчёт смет;
- подбор отделочных материалов, предметов мебели, декоративных элементов и прочего;
- контроль работы по воплощению проекта;
- слежение за главными этапами реализации проекта.
Могут быть и дополнительные обязанности. На это влияет сфера, в которой он работает. Многое зависит от масштаба, характера заказа, выделенной суммы, трудовых ресурсов и сложности разработанного проекта.
Профессия дизайнер-декоратор интерьера относится к творческим специальностям, однако, кроме умения создавать, человек должен обладать практической жилкой. Если последнего качества не будет, то постоянно будут срываться сроки, а готовый результат может получиться вообще не таким, каким он планировался.
Специалист должен обладать такими теоретическими знаниями, как:
- Популярные направления в дизайне и декоре интерьеров.
- Процессы и практические мероприятия декорирования интерьера.
- Основы живописи и рисунка, цвета, композиции, перспективы.
- Принципы проектной графики.
- Свойства и особенности отделочных материалов.
- Основы психологии индивидуального видения визуальной информации.
- Контакты с рынком мебели, текстиля, декора и прочего.
- Создание декораторских и художественных дизайн-проектов, начиная с эскизов, заканчивая готовым результатом.
- Построение чертежей и планов.
- Создание 3D модели проекта (зарисовки, прирезка, макет).
- Разработка коллажных проектов.
- Принятие решений о том, какую приобрести мебель, светильники, аксессуары и декор, чтобы всё это вписывалось в выбранную концепцию.
- Умение работать в программах для 2D графики (Adobe CC, CorelDraw и прочие).
- Навык работы с 3D графикой (Autodesk AutoCAD, Autodesk 3DS Max и прочими), рендерами (V-Ray и т.д.).
- Продумывание текстильного образа помещения.
- Понимание и умение работать с разными стилями.
Для вас подарок! В свободном доступе до 05.11 —>
Скачайте ТОП-10
бесплатных нейросетей
для дизайнера
Помогут находить референсы и изображения в 2 раза быстрее
Чтобы получить подарок, заполните информацию в открывшемся окне
Какими личностными качествами обладает дизайнер-декоратор:
- Клиентоориентированность, способность общаться с клиентами.
- Навык профессионального общения.
- Тайм-менеджмент, грамотное построение рабочего процесса.
- Независимость деятельности.
- Коллективный труд.
- Многозадачность, способность работать одновременно над несколькими заказами.
- Повышенное внимание к мелочам.
- Ответственность за качество воплощения.
- Саморазвитие, постоянное изучение новой информации, повышение квалификации.
Профессионал своего дела ещё при первом разговоре с клиентом должен представить общую картину. Ему необходимо сразу понять, какие могут быть изъяны у проекта, а также проанализировать желания заказчика и грамотно объяснить возможность/невозможность их воплощения.
Задачи дизайнера-декоратора
Главная цель дизайнера-декоратора состоит в том, чтобы обустроить пространство максимально комфортно и уютно. При это надо сделать не просто красивый интерьер, а воплотить в реальность желания клиента. Специалист должен брать во внимание привычки и идеи заказчика, его образ жизни и состав семьи. К тому же надо учитывать технические характеристики помещения, выделенные средства и сроки на выполнение.
Дизайнер-декоратор хорошо разбирается в свойствах строительных материалов и как они ведут себя при эксплуатации. Какие стены можно возвести, а какие разрушить. Влияние цвета на эмоциональное и физическое состояние человека. Как гармонично использовать в одном интерьере старую и новую мебель.
Специалист разбирается в габаритах мебели, как её поставить, чтобы было достаточно места для комфортного передвижения. Он может распланировать систему вентиляции, рассчитать смету, ему понятна техническая документация. Помимо этого, он знает стоимость различных материалов и способы сэкономить на них.
Дарим скидку от 60%
на обучение «Дизайнер интерьеров» до 05 ноября
Уже через 9 месяцев сможете устроиться на работу с доходом от 150 000 рублей

В чём заключается работа дизайнера-декоратора:
- Проводит встречи с клиентами для обсуждения возможного будущего проекта. Выясняет желания, изучает референсы. Уточняет количество выделенных средств, сроки и ограничения.
- Проводит замеры в помещении и делаете фотографии. Это позволяет ему узнать все необходимые размеры, где проходят коммуникации, наличие мокрых зон. Отталкиваясь от полученной информации, он создаст план помещения с указанием размеров.
- Разрабатывает планировочные решения, где обозначает разные зоны, расставляет предметы мебели. Как правило, создаётся несколько вариантов, чтобы заказчик мог выбрать тот, что ему больше понравится.
К примеру, вы являетесь хозяином двухкомнатной квартиры с отдельной кухней, но вам хочется иметь три отдельных помещения и место для семейного времяпрепровождения. В одном варианте специалист может объединить кухню и гостиную. В другом – разместить кухню вместо коридора. В третьем – поделить большое помещение на два маленьких. Если менять стены не получится, то дизайнер сделает несколько планов расположения мебели и выделит зону для каждого члена семьи.
Из предоставленных вариантов заказчику и дизайнеру надо выбрать один, который останется доработать и продумать все мелочи. На этом этапе специалист:
- Подбирает подходящие под концепцию предметы интерьера и цвет мебели, текстиль, освещение, отделочные материалы.
- Разрабатывает 3D-визуализацию проекта, коллажи, зарисовки, рисунки. Это поможет заказчику увидеть результат ещё до его достижения.
- Работает над планами и чертежами: план расположения электрических приборов и сантехники, дверей и окон, мебели, напольных покрытий, ведомость материалов. Все эти чертежи и техническую документацию дизайнер разрабатывает в компьютерных программах, после чего отдаёт строителям, которые будут опираться на них в ходе ремонта.
- Находит поставщиков, заказывает и решает вопросы с доставкой строительных материалов и мебели. Специалист знает места, где лучше приобрести необходимые предметы, материалы для отделки, и как сделать закупку более выгодный для клиента.
- Ищет и заключает договор со строительной бригадой. При этом он понимает, какими навыками должны обладать рабочие, чтобы в точности воплотить проект в жизнь.
- Контролирует все этапы стройки и ремонта. Следит за сроками, качеством и тем, насколько строители придерживаются планов.
- Когда завершится ремонт, дизайнер начинает заниматься расстановкой мебели, размещением аксессуаров, работает над декором в соответствии с выбранной концепцией.
- В конце остаётся сдать готовый проект заказчику и обсудить возможность фотосъёмки и связные с ней вопросы.
Всем этим дизайнер-декоратор может заниматься сам, или же разделить обязанности с другими специалистами, а у него в это время появится возможность следить за реализацией проекта и решать конкретные задачи. К примеру, разработать и утвердить план расположения мебели, сделать её подбор и заняться отделкой.
Основные инструменты для работы дизайнера-декоратора
Для профессионального декоратора главным инструментом является его голова, в которой и появляются интересные идеи.
Чтобы сделать визуальное представление своих задумок, можно использовать следующие компьютерные программы:
- Adobe Photoshop – это самая распространённая программа у дизайнеров. Она представляет собой графический редактор, в котором можно работать в основном с растровыми картинками.
- Figma. В этой программе можно создавать векторные и растровые изображения, а также разрабатывать прототипы приложений или интернет-ресурсов.
- Corona. С помощью этой программы создаётся полноценная картинка на основе заготовки графических элементов.
- 3DMax представляет собой ПО, с помощью которого можно как создавать разнообразные графические объекты, так и размещать их в построенной «комнате». 3DMax позволяет сделать качественную визуализацию любого интерьера.
- 3D Hamster. Это хранилище, где есть разнообразные объекты, которые могут понадобиться при разработке интерьера.
Только до 2.11
Скачай подборку материалов, чтобы гарантированно найти работу в IT за 14 дней
Список документов:

ТОП-100 площадок для поиска работы от GeekBrains

20 профессий 2023 года, с доходом от 150 000 рублей

Чек-лист «Как успешно пройти собеседование»
Чтобы зарегистрироваться на бесплатный интенсив и получить в подарок подборку файлов от GeekBrains, заполните информацию в открывшемся окне
Помимо этого, большое количество дизайнеров-декораторов занимаются созданием иллюстраций на графических планшетах. Для этого нужны специальные программы, такие как Sketchbook, Painter Lite, ArtRage 4 и прочие.
Варианты обучения на дизайнера-декоратора
Чтобы стать дизайнером-декоратором, надо для начала узнать, где учиться на эту специальность. Сейчас есть два варианта: вуз либо короткие курсы.
Высшее учебное заведение
Самыми лучшими архитектурно-художественными вузами России являются:
- Московский государственный академический художественный институт имени Сурикова.
- МГХПА имени Строганова.
- Академический институт живописи, скульптуры и архитектуры имени Репина.
- Московский государственный университет культуры и искусств.
- Санкт-Петербургская государственная художественно-промышленная академия.
В них можно получить основное художественное образование. В течение пяти лет обучения студенты получат необходимые профессиональные знания, будут проходить практики, познакомятся с нужными людьми. Когда учёба закончится, выпускники могут работать по профессии или начать преподавать. Но надо понимать, что на обучение уйдёт много времени и денег.
К тому же бюджетных мест в художественных вузах, как правило, мало, а их дипломы существенно влияют на дальнейшее трудоустройство, потому что высоко ценятся.
Кратковременные курсы
Принцип курсов по профессии дизайнер-декоратор состоит в недолгосрочном (от 3-х недель до года) и более узком изучении. Их цель в том, чтобы сделать из вас действующих специалистов, поэтому больше внимания акцентируется на навыке общения с клиентами и умении делать самопрезентацию. Такие курсы служат отличным продолжением обучения в высшем учебном заведении и помогают лучше сосредоточиться на данной профессии.
Тем не менее, чтобы учиться на этих курсах, необязательно иметь образование, потому что они являются общедоступными. Экзаменовать вас тоже никто не будет. После прохождения курса по декорированию выдаются дипломы. Самым главным нюансом такого обучения является стоимость – все курсы только платные.
Назвать конкретную цену не получится, потому что курсы разные, как и их стоимость, которая зависит от длительности обучения и объёма программы. Есть курсы для новичков, а есть те, которые подходят только профессионалам, желающим повысить свою квалификацию. Существуют программы, в которых студентов отправляют на практику в другие страны, но стоимость таких курсов очень высокая.
Как же стать дизайнером-декоратором человеку, который практически ничего не знает об этой профессии? Желательно всё же начать обучение на курсах декорирования и стилизации интерьеров. Продолжительность программы может составлять как 5 месяцев, так и год. На протяжении этого времени вы освоите основы специальности, теорию и историю декорирования, колористику, композицию, эргономику, приобретёте знание главных художественных приёмов, научитесь создавать макеты и планы, узнаете о свойствах декоративных материалов.
Вам объяснят, как создать яркое и привлекательное портфолио, общаться с клиентами, рассчитывать сметы, демонстрировать свои проекты, а это всё является очень важной частью профессии. Цена у таких курсов немаленькая – 120 000–190 000 рублей, но после обучения можно действительно построить успешную карьеру в этом направлении.
Главное – получить основу, которую в дальнейшем можно дополнять семинарами, тренингами и мастер-классами. Они могут быть и на творческие темы, и направленными на улучшение деловых навыков. Состоят подобные семинары из 2–12 занятий, а стоимость их начинается от 4000 и может доходить до 30000 рублей.
В целом, дизайнеру-декоратору необязательно иметь высшее образование. Успешную карьеру строят люди, которые просто прошли курсы. Намного важнее в этом направлении индивидуальность, хороший вкус и практические навыки. Профессионал своего дела постоянно развивается и изучает новые стороны своей специальности. Никогда успешный человек не будет утверждать, что знает абсолютно всё в той сфере, в которой он работает.
Зарплата и поиск вакансий дизайнера-декоратора
Человека, который выбрал это направление, обязательно будет интересовать, сколько зарабатывает дизайнер-декоратор. В начале пути в дизайнерском агентстве зарплата составит 20–30 тыс. рублей в месяц. Более опытные специалисты получают от 40–50 тыс. рублей в месяц. Довольно часто людей этой профессии нанимают в магазины штор, салоны элитной мебели, организаторами праздников, где заработная плата может быть 80–120 тыс. рублей. Если выбрать фриланс и создать базу клиентов и хорошее портфолио, то в месяц можно заработать 80 тыс. руб. и выше.
Найти заказчиков можно через сервисы с вакансиями, биржи фриланса или социальные сети.
Ниже перечислены несколько сервисов, которые могут помочь с поиском работы:
- HH.ru.
- SuperJob
- Яндекс работа.
Найти вакансию сможет любой. Сначала надо выбрать сервис, в поисковой строке написать название профессии и запустить поиск. Далее выбираете самые подходящие вакансии и отправляете в ответ на них своё резюме.
На биржах фриланса вы можете предложить свои услуги. Вам надо зарегистрироваться на сервисе и разместить услугу для продажи. Заказчики будут сами вам писать, а после выполнения работы платить деньги.
В соцсетях есть множество сообществ, через которые можно найти работу. С помощью поиска найдите группы с вакансиями или сообщества, посвящённые конкретно вашей профессии. Останется выбрать вакансию и отправить своё резюме.
Первая работа и карьерный рост дизайнера-декоратора
У дизайнера-декоратора есть несколько вариантов, где и как он может работать: стать фрилансером или пойти в наем в дизайнерскую студию либо в другие организации, которым требуются специалисты из этой отрасли.
Фриланс
Специалисту необходимо самостоятельно искать клиентов. Помогут в этом биржи, социальные сети, сайты, выход на заказчиков через знакомых. В этом формате все организационные и рабочие моменты, а также вся ответственность лежат исключительно на вас.
Первое время надо будет работать для портфолио, поэтому придётся браться за любые заказы, даже если они скучные и с маленькой оплатой. На таких проектах вы сможете набить руку и повысить качество своих работ. Чем выше будет ваш опыт и репутация, а также качественнее портфолио, тем быстрее вы будете находить новых заказчиков. Вы можете даже стать владельцем собственной студии.
Зачем нужен декоратор?
На российском рынке декоратор — профессия новая. Точнее, надолго забытая за н
На российском рынке декоратор — профессия новая. Точнее, надолго забытая за ненадобностью и недавно востребованная вновь. Теперь на оформление частного жилья тратятся большие деньги, поэтому творчески распоряжаться дорогим дизайном, фактурами и аксессуарами, а также формулировать идеи должен профессионал. О своей работе рассказывают известные российские декораторы.
Дмитрий Великовский (Москва), бюро Artistic Design
— Что входит в обязанности декоратора?
— Архитектор делает коробку и общую отделку, все остальное, сообразуясь со вкусами и статусом заказчика,— декоратор. Он придумывает концепцию, он отвечает за техническую часть проекта. Он и художник, и логистик.
На Западе есть профессионалы, совмещающие работу архитектора и декоратора. У архитекторов скорее сухой подход к дизайну. Декораторы раскрепощеннее, у них больший арсенал средств. Специфика профессии архитектора — пытаться решить интерьер архитектурными средствами. При минимуме вещей. Это высочайший уровень мастерства. В России таких людей практически нет.
— Сколько в Москве декораторов западного уровня?
— Практикующих профессиональных декораторов шесть-семь. Все остальные имеют косвенное отношение к этой профессии. К сожалению, большинство наших декораторов принципиально от заказчиков не отличаются и просто не представляют себе, чем они занимаются.
— Как формируется цена на услуги декоратора?
— Стандартный западный подход — определенный процент от бюджета поставки, 10-20%. Известные декораторы берут минимум 15%. В Англии, если интерьер стоит $500 тыс., работа по разработке декорации и управлению проектом может стоить до $100 тыс. В России мало людей, работающих по этому принципу.
— На чем основан этот принцип ценообразования?
— Декоратор несет большую ответственность. На Западе декораторская фирма является поставщиком всего, что у клиента есть в интерьере. Для оформления дома может быть задействовано до 30-40 фирм, и ни один заказчик не в состоянии самостоятельно справиться с кучей мелких проблем, связанных с реализацией проекта, поддержанием интерьера, гарантийным ремонтом. Российские заказчики пытаются экономить и пользуются консультативными услугами декоратора.
— Какие вкусы преобладают у российских заказчиков?
— Есть разные сегменты рынка. Много людей с консервативными вкусами, предпочитающих традиционную архитектуру и интерьер. Есть поклонники минимализма, хотя в Европе мода на него уже прошла. Есть любители этнических, ориентальных интерьеров. Есть журнал «Салон» со специфическими местными российскими интерьерами. Это направление мне чуждо и непонятно. Но бывают клиенты, предпочитающие именно его. Их немало. Никто не занимался статистикой. Наше бюро предлагает клиентам классику, переложенную на современный язык, «нечистый» минимализм и микс из разных стилей.
Андрей Дмитриев (Санкт-Петербург)
— Как вы определяете вкусы заказчика?
— С заказчиками я стараюсь беседовать скорее как доктор. Чтобы понять пристрастия человека, надо понять, где он комфортно себя чувствует. Люди сами не знают, чего хотят, и я должен им помочь. Мы смотрим пакет образов. Это стандартная практика нормального западного декоратора — показывать человеку кусочки тканей, вещи, цвета. Журнальные картинки смотрим редко. Если заказчик ткнет пальцем в конкретный интерьер и скажет: «Я хочу вот так», мне это будет неинтересно. Ну какой мне смысл кого-то копировать? Поэтому пакет образов дает наиболее чистое представление о вкусах. Ведь образ не конкретен. Тут остается поле для экспериментов. Главное — определить базовое направление: куда идти.
— У вас нет бюро. Как вы ведете проекты?
— Я одиночка, но вокруг меня много народа, с которым я могу работать. Сам все не делаю. Разбиваю проект на части и поручаю каждому свое задание. Но все мелочи я, как правило, подбираю лично.
— Сколько стоит декорация жилья и сколько времени уходит на реализацию проекта?
— Сегодня декоратор вправе назначать любую цену, потому что на десять миллионов человек приходится один декоратор. В Москве работа декоратора стоит от $100 за квадратный метр. Верхнюю планку назвать нельзя, она индивидуальна. По западной практике это 20% от стоимости проекта. На реализацию проекта нужно не меньше полугода. Если проект большой, интересный, на него может уйти вся жизнь. Быстро собрать хорошие вещи очень дорого. Но пока российские заказчики не готовы ждать дом три-четыре года. Вообще, представление о работе декоратора не сформировано. Главная ошибка в отсутствии респекта. Заказчики думают, что все очень просто, декоратор — это так, мальчик какой-то, который выбирает унитазы.
Анна Муравина, декоратор (Москва)
— Как объяснить жене, что вкус ее превосходен, но нужно звать специалиста?
— Есть вещи, которые сможет сделать только профессионал. Например, декоратор знает психологическое и физиологическое воздействие цветов. Знает, что определенный оттенок синего цвета не должен преобладать в жилом интерьере, а красный цвет повышает артериальное давление.
Кроме того, декоратор поможет распределить бюджет, чтобы не было три четверти всех денег потрачено на кухню или ванну (это старая привычка советских времен — ремонт дома начинать с подсобных помещений).
Смелость современного интерьера и его индивидуальность строится на сопоставлении несочетаемых предметов, тканей, фактур. Дилетанту трудно работать с дорогими вещами, а тем более сочетать вещи несопоставимой стоимости. Только опытный декоратор может антикварное кресло XVIII века поставить не на рокайльный ковер, а на грубо покрашенный дощатый пол, на котором оно будет выглядеть как настоящая драгоценность. Артистично нарушать законы можно, только хорошо ими владея. Здесь одного вкуса недостаточно.
Если человек сам создает себе жилище, он никогда не представляет его полностью, во всех деталях. Он мыслит категориями: шкафчик такой, а диванчик такой. Предугадать все сочетания цветов и пропорций, предсказать, как они реально будут взаимодействовать, очень трудно — нет профессионально натренированного воображения.
И наконец, очень трудно делать дом для себя. Очень тяжело взглянуть на себя со стороны. Декоратор выступает одновременно и как художник, и как психоаналитик. Поэтому профессиональные декораторы, оформляя свое собственное жилье, всегда консультируются с коллегами.
Интервью взяла МАРИЯ САВОСТЬЯНОВА
- «Интерьер». Приложение №91 от 30.05.2002, стр. 28
- Архитектура подписаться отписаться
Python декораторы на максималках. Универсальный рецепт по написанию и аннотированию от мала до велика
Декорирование функций — это, наверное, самая сложная среди базовых и самая простая среди продвинутых фич языка Python. С декораторами, наверное, знакомы все джуны (хотя бы в рамках подготовки к собеседованиям). Однако, крайне мало разработчиков пишут их правильно. Особенно принимая во внимания тенденции последних нескольких лет к аннотированию всего и вся. Даже популярные open-source проекты (если основная часть их кода была написана до 2018 года) вряд ли дадут вам примеры декораторов, отвечающих всем современным требованиям к коду.
Изначально статья должна была получиться на 2 минуты, но с высоким порогом входа, однако, я не могу просто вывалить контент для 5ти таких же отбитых энтузиастов. Придется пошагово объяснять его всем. Прошу прощения за лонгрид и большое количество кода.
В рамках статьи мы разберемся с декорированием функций в Python от простого к самому сложному. Рассмотрим, как их правильно писать и аннотировать, чтобы другие потребители вашего кода не страдали от близкого знакомства с ним. Уверен, что даже если вы чрезвычайно опытный разработчик, вы найдете для себя полезные советы (хотя и можете пропустить солидную часть материала).
Материал актуален для версий Python3.7-3.11 (и частично 3.12), однако, концептуальные изменения с выходом новых версий могут быть разве что в появлении новых более удобных типов для аннотаций.
Давайте разбираться с декораторами.
И небольшое оглавление, для тех, кто не хочет заблудиться:
- Декораторы
- Простейший декоратор
- Декоратор с параметрами
- Декоратор Шредингера
- Аннотирование декораторов
- typing.Callable
- typing.TypeVar
- typing.ParamSpec
- Аннотируем Шредингера
- Обозначаем проблему
- Предлагаем решение
- Делаем интереснее
- Последний совет
Кто такие декораторы и зачем они нужны
Декораторы функций — это простой способ модификации поведения любой функции без внесения изменения в ее код. Они часто лежат в основе многих библиотек и вы наверняка с ними знакомы, даже если и никогда не писали (привет FastAPI, Flask и миллионы других).
Декораторы позволяют вам выполнить произвольный код до/после/вместо вызова функции, модифицируя ее входные аргументы, результат выполнения и добавляя различные сайд-эффекты.
Примеры отличного функционала для реализации через декорирование:
- ретраи — tenacity
- логирование ошибок — loguru
- сериализация входящих данных — FastDepends
- регистрация обработчиков — любой HTTP (и не только) фреймворк
Для простоты понимаю декораторов новичками я всегда вдалбливаю им следующее определение:
Декоратор — это функция, принимающая на вход функцию, и возвращающая (другую) функцию
P.S. На самом деле, это может быть и не функция, а любой Callable объект, да и декорировать классы тоже можно. Но обо всем по порядку.
Простейший декоратор
Итак, давайте напишем самый-самый простой декоратор исходя из его определения.
def decorator( # это функция call # принимает на вход функцию ): def wrapper(*args, **kwargs): # код до оригинальной функции r = call(*args, **kwargs) # код после оригинальной функции return r return wrapper # возвращает другую функциюТеперь у нас есть декоратор, который
не делает ничегопринимает любые входящие аргументы и передает их в задекорированную функцию.Процесс декорирования выглядит просто как вызов функции декоратора:
def call(a: int) -> str: return str(a) decorated_call = decorator(call) # вызов как обычной функции assert decorated_call(1) == "1"Однако, в Python есть немного сахара и на этот случай. Я думаю, следующий синтаксис вам знаком:
@decorator def call(a: int) -> str: return str(a)Данный код также применяет декоратор к объявленной функции, однако присутствуют некоторые нюансы, о которых стоит знать:
- ваша оригинальная функция call замещается функцией wrapper , и вы больше не можете получить доступ к call в глобальной видимости;
- в ваш декоратор передается ровно один аргумент — декорируемая функция. Если вы хотите передавать дополнительные аргументы, нужно использовать другие приемы.
Небольшой совет: возьмите в привычку всегда декорировать ваш wrapper с помощью functools.wraps . Эта функция копирует всю служебную метаинформацию о декорируемой функции в функцию-декоратор (название функции, докстринги, список входящих аргументов, их типы и тд).
Это нужно как минимум для того, чтобы библиотеки, получающие информацию о ваших функциях через модуль inspect работали корректно (тот же FastAPI не сможет распознать аргументы вашей функции без этого).
Всего пара «лишних» строк кода, не ленитесь:
from functools import wraps def decorator(func): @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapperДекоратор с параметрами
Если вы более опытный разработчик, то должны были сталкиваться и с подобным синтаксисом (хотя бы в примере выше):
@some_decorator(arg1, arg2) def func(): .Первая попытка осмысления может вогнать в ступор: декоратор же принимает на вход функцию, а тут какие-то аргументы?
Все достаточно прозаично: some_decorator в этом случае не декоратор, а функция, возвращающая декоратор.
Т.е. процесс декорирования (без сахара) на самом деле выглядит немного по другому:
# обычный декоратор decorated_func = decorator(call) # декоратор с параметрами decorator_wrapper = decorator(arg1, arg2) decorated_func = decorator_wrapper(call) # или в одну строку decorated_func = decorator(arg1, arg2)(call)Надеюсь, вы уже догадались, как пишется подобный декоратор, но я все-таки приведу пример:
def decorator_wrapper(arg1, arg2): def real_decorator(func): # объявляем декоратор @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper return real_decorator # возвращаем декоратор @decorator_wrapper(1, 2) def func(): .Так как декоратор в этом случае — замыкание, то вы имеете доступ к arg1 и arg2 на любом уровне вложенности.
Еще одно важное уточнение: процесс декорирования происходит на этапе первого прохождения интерпретатором Python вашего кода (когда Python получает представление об объектах, которыми он может оперировать в рантайме).
Т.е. в самом рантайме (процесс вызова функции) во всех сценариях декорирования будет выполнен только код, находящийся внутри wrapper ‘а.
Сам же код декоратора будет выполнен сразу при старте вашего приложения, как только интерпретатор дойдет до строки @decorator . Именно поэтому все декораторы должны быть объявлены как синхронные функции. Даже если они являются декораторами для асинхронных функций (в таком случае асинхронным будет объявлен wrapper ).
Декоратор Шредингера
Так, здесь у нас собрались уже матерые разработчики, поэтому и обсудим юзкейсы по-интереснее.
Вы, конечно, знакомы с декораторами Шредингера, которые можно использовать и так, и так:
@pytest.fixture def simple_fixture(): . @pytest.fixture(scope="session") def session_fixture(): . @dataclass class SimpleDataclass: . @dataclass(slots=True) class SimpleDataclass: .Вы когда-нибудь задумывались как такое написать?
Я вот не задумывался. А потом как задумался! — и сразу попал в ступор.
Ведь это одна функция (точно одна, в питоне же нет перегрузок,
или есть), хотя применяется она двумя совершенно разными способами. Объединить их в один тоже как-то проблематично. В первом случае у нас 2 уровня вложенности внутри декоратора, во втором — 3. В общем, загадка.На самом деле, никакой магии здесь тоже нет. Проблема решается добавлением четвертого уровня вложенности (а то 3ех нам «мало»).
таким образом в ваш декоратор передается ровно один аргумент — декорируемая функция
Помните такое? Это наш ключ к решению загадки декоратора Шредингера.
Совмещаем обычный декоратор и декоратор с параметрами вместе и получаем что-то такое:
def schrodinger_decorator( call = None, *, arg1 = None, arg2 = None, ): .При этом все аргументы должны иметь значения по умолчанию так как в одном случае у нас будет передаваться только call , в другом — только дополнительные аргументы.
Затем мы отдельно пишем декоратор с параметрами еще раз:
def decorator_wrapper(arg1, arg2): def real_decorator(func): @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper return real_decoratorТеперь нам осталось только разрешить два наших сценария проверкой if call is None .
def schrodinger_decorator( call = None, *, arg1 = None, arg2 = None, ): wrap_decorator = decorator_wrapper(arg1, arg2) # если мы использовали декоратор # как декоратор с параметрами if call is None: return wrap_decorator # если мы использовали декоратор как обычный ## arg1 и arg2 при этом принимают ## значения по умолчанию else: return wrap_decorator(Call)# call=func, arg1=None, arg2=None @schrodinger_decorator def func(): . # call=None, arg1=1, arg2=2 @schrodinger_decorator(arg1=1, arg2=2) def func(): .Аннотирование декораторов
Современный синтаксис Python невозможно представить без аннотации типов. Аннотация обеспечивает работу автодополнения, а других разработчиков — информацией о типах входящих и исходящих параметров, да и вообще дает много других плюшек, значительно повышающих Developer Experience.
Однако, балуясь с декораторами, эти аннотации очень легко сломать. Поэтому давайте разбираться, как не прострелить себе и другим ноги.
Нам понадобяться следующие братья:
- typing.Callable — базовый тип любого вызываемого объекта в Python (функции в том числе)
- typing.TypeVar — переменная типа, позволяет синхронизировать аннотации различных параметров функции друг с другом
- typing.ParamSpec (до py3.10 использовать из typing_extensions ) — общая аннотация произвольных аргументов функции
Достаточно тяжело объяснить без примеров, поэтому давайте на них посмотрим.
typing.Callable
Callable используется для «вызываемых» объектов (функций). Это generic объект, у которого нужно указать 2 типа:
- тип входящих аргументы
- тип результата
# любые входящие аргументы, любой результат Callable[. Any] # функция вида `func(a: int, b: float)` Callable[[int, float], Any] # функция вида `func(a: int, b: float) -> int` Callable[[int, float], int]typing.TypeVar
T = TypeVar("T") def func(a: T) -> T: .В данном случае мы объявляем функцию, которая принимает аргумент a любого типа, но ее ответ должен быть того же типа, что a :
int -> int, str -> str, float -> float , e.t.c
Таким образом мы синхронизируем типы в рамках аннотации.
typing.ParamSpec
ParamSpec был специально придуман для декораторов. С помощью этого типа можно синхронизировать произвольные входящие аргументы функций. Давайте посмотрим, как это работает:
F_Spec = ParamSpec("F_Spec") F_Return = TypeVar("F_Return") def decorator( call: Callable[ F_Spec, # функция с произвольными входными аргументами F_Return ] ) -> Callable[ F_Spec, # функция с теми же входными аргументами F_Return ]: @wraps(func) def wrapper( *args: F_Spec.args, # эти аргументы **kwargs: F_Spec.kwargs # эти аргументы ) -> F_Return: return call(*args, **kwargs): return wrapperТак выглядит абсолютно правильное аннотирование декораторов с выхода py3.10
И закрепим на примере декоратора с параметрами:
def decorator_wrapper( arg1: Any, arg2: Any ) -> Callable[ # возвращаем реальный декоратор, который # принимает на вход функцию [Callable[F_Spec, F_Return]], # возвращает такую же функцию Callable[F_Spec, F_Return] ]: .Кстати, манипулируя типом, возвращаемым декоратором, вы можете изменить автокомплиты задекорированной функциии (но с этим вы поиграетесь сами).
Аннотируем Шредингера
А как нам быть в случае декоратора Шредингера? Он то уж точно ломает стандартную аннотацию функции. При этом тип возвращаемого значения зависит от того, как мы его используем.
Т.е. по факту он имеет 2 возможных варианта декорирования:
# аннотация обычного декоратора def schrodinger_decorator( call: Callable[F_Spec, F_Return], *, arg1: None = None, arg2: None = None, ) -> Callable[F_Spec, F_Return]: . # аннотация декоратора с параметрами def schrodinger_decorator( call: None = None, *, arg1: Any = None, arg2: Any = None, ) -> Callable[ [Callable[F_Spec, F_Return]], Callable[F_Spec, F_Return] ]: .Хорошо, что есть typing.overload , который создан как раз для этого: данный декоратор позволяет объявить несколько аннотация для одной функции в зависимости от входящих и исходящих аргументов.
Просто объединяем оба варианта в один реальный и добавляем несколько вариантов аннотаций:
# аннотация обычного декоратора @overload def schrodinger_decorator( call: Callable[F_Spec, F_Return], *, arg1: None = None, arg2: None = None, ) -> Callable[F_Spec, F_Return]: # тело должно быть пустым # этот код только для аннотации . # аннотация декоратора с параметрами @overload def schrodinger_decorator( call: None = None, *, arg1: Any = None, arg2: Any = None, ) -> Callable[ [Callable[F_Spec, F_Return]], Callable[F_Spec, F_Return] ]: . # реальный вариант с объединенной аннотацией def schrodinger_decorator( call: Callable[F_Spec, F_Return] | None = None, *, arg1: Any | None = None, arg2: Any | None = None, ) -> Callable[ [Callable[F_Spec, F_Return]], Callable[F_Spec, F_Return] ] | Callable[ F_Spec, F_Return ]: wrap_decorator = decorator_wrapper(arg1, arg2) if call is None: return wrap_decorator else: return wrap_decorator(Call)Class-based декораторы
Как мы все уже точно знаем, процесс декорирования выглядит следующим образом:
decorated_func = decorator(func) result = decorated_func(*args, **kwargs)А что если мы хотим сделать что-то такое?
decorated_func = DecoratorClass(func) result = decorated_func(*args, **kwargs)Никаких проблем, давайте сделаем!
class DecoratorClass: def __init__(self, func): # выполняется при декорировании self.original_call = func def __call__(self, *args, **kwargs): # выполняется при вызове return self.original_call(*args, **kwargs)А что это нам дает? Ну, а вот это уже самое интересное.
Самое интересное
Обозначаем проблему
При написании различных фреймворков декораторы часто используются не для модификации функции как таковой, а для регистрации этой функции как обработчика где-то внутри.
# любой HTTP фреймворк @app.get("/") def handler(. ): .А что если мы хотим регистрировать одну и ту же функцию несколько раз?
@app.get("/") @app.get("/index") def handler(. ): .Обычно для таких сценариев используют декоратор, который возвращает оригинальную функцию без изменений:
# пример из FastAPI class FastAPI: def get(route: str): # декоратор с параметром def decorator(func): self.routes.append(APIRoute(func)) return func # возвращаем без измененийТеперь, сколько декораторов не вешай, они все будут обрабатывать функцию независимо.
Но что если мы хотим знать, что функции была задекорирована до нас? А кем она была задекорирована? Может быть тогда можно пропустить часть работы? А если мы все-таки хотим добавить фунции дополнительное поведение, но только один раз?
Предлагаем решение
Уже становится сложно. В этом случае нам и поможет class-based декоратор. Мы просто замещаем нашу функцию классом, а во всех следующих декораторах проверяем, пришла нам функция или уже класс-декоратор. На основе этого мы и принимаем решение, что делать дальше.
class FuncWrapper: wrapped_call: Callable def __init__(self, call): if not isinstance(call, FuncWrapper): self.wrapped_call = call else: # функция уже задекорирована # обрабатываем этот сценарий def __call__(self, *args, **kwargs): return self.wrapped_call(*args, **kwargs) @FuncWrapper @FuncWrapper def func(a: int) -> str: .Однако, нам нужно еще и не сломать аннотирование исходной функции, как мы помним. Тут нам пригодится typing.Generic : этот класс позволяет нам объявлять свой класс как generic и синхронизировать аннотации между различными атрибутами и методами.
from typing import Generic, Callable, ParamSpec, TypeVar F_Spec = ParamSpec("F_Spec") F_Return = TypeVar("F_Return") class FuncWrapper(Generic[F_Spec, F_Return]): wrapped_call: Callable[F_Spec, F_Return] def __init__( self, call: Callable[F_Spec, F_Return] ) -> None: if not isinstance(call, FuncWrapper): self.wrapped_call = call def __call__( self, *args: F_Spec.args, **kwargs: F_Spec.kwargs, ) -> F_Return: return self.wrapped_call(*args, **kwargs) @FuncWrapper def func(a: int) -> str: .Однако, почему-то в разных версиях IDE код работает немного по-разному: где-то аннотации корректно переносятся, где-то нет.
Поэтому для себя я использую небольшой трюк, который работает везде: пишем «лишнюю» функцию. Кстати, это же является и решением для написания декораторов с параметрами при таком сценарии.
def decorator( call: Callable[F_Spec, F_Return] ) -> FuncWrapper[F_Spec, F_Return]: return FuncWrapper(call) @decorator def func(a: int) -> str: .Ну а в рамках это класса вы можете добавлять дополнительные атрибуты, в которых хранить информацию о том, кто и как уже задекорировал эту функцию.
class FuncWrapper: wrapped_call: Callable decorators: list[object] def __init__(self, call): if not isinstance(call, FuncWrapper): self.wrapped_call = call self.decorators = [] else: self.wrapped_call = call.wrapped_call self.decorators = call.decorators self.decorators.append(self)Делаем интереснее
Хранить информацию о том, кто и как уже задекорировал функцию мы научились. Но проблема в том, что декораторы выше нас знают, кто там был до него. А вот те, кто ниже не знают о декораторах сверху. Непорядок какой-то, не находите?
@FuncWrapper # знает о соседе снизу @FuncWrapper # ничего не знает def func(a: int) -> str: .Проблем, вроде бы нет, но они могут быть, если вы имеете доступ к объектам промежуточных декораторов (просто поверьте, моя нога до сих пор болит).
Немного контекста: в новой мажорной версии моего фреймворка для работы с брокерами сообщений Propan вы cможете строить пайплайны обработки данных следующим образом:
@broker.subscriber("in-topic") # отсюда потребляем сообщения @broker.publisher("out-topic") # сюда отправляем ответ async def handler(msg): return "processed"Соответсвенно, не хорошо заставлять пользователя фреймворка помнить, что publisher должен быть объявлен до subscriber (который использует информацию о зарегистрированных publisher’ах). Пришлось исхитрятся, чтобы они могли быть объявлены в любом порядке.
Решение лежит на уровне метапрограммирования: в случае, если мы декорируем уже задекорированную функцию, мы не копируем поля класса в текущий объект, а действительно используем тот же самый объект. Таким образом, во всех декораторах мы оперируем одним и тем же объектом, и поля, дописанные выше (или даже извне), будут видны на всей глубине «матрешки».
Здесь нам поможет метод __new__ .
Метод __new__ — настоящий конструктор класса в Python. Именно он создает объект, поля которого затем инстанциируются в методе __init__ . Если мы хотим избежать создания нового объекта при каких-либо условиях, нам нужен именно этот парень.
class FuncWrapper(Generic[F_Spec, F_Return]): wrapped_call: Callable[F_Spec, F_Return] decorators: list[object] def __new__(cls, call: Callable[F_Spec, F_Return]) -> Self: if isinstance(call, FuncWrapper): # если функция уже задекорирована, # возвращаем тот же объект return call # иначе конструируем новый объект return super().__new__(cls) def __init__(self, call: Callable[F_Spec, F_Return]) -> None: # метод __init__ будет вызван в обоих ветках __new__ if not isinstance(call, FuncWrapper): self.wrapped_call = call self.decorators = [] self.decorators.append(self) # все все знают @FuncWrapper @FuncWrapper def func(a: int) -> str: .Последний совет
Некоторые библиотеки определяют, является ли функция асинхронной с помощью стандартного метода asyncio.iscoroutinefunction (тот же FastAPI или мой FastDepends).
# исходный код asyncio def iscoroutinefunction(func): """Return True if func is a decorated coroutine function.""" return (inspect.iscoroutinefunction(func) or getattr(func, '_is_coroutine', None) is _is_coroutine)Проверка на наличие _is_coroutine является костылем для того, чтобы объект AsyncMock также распознавался как асинхронная функция. Поэтому предпочтительнее использовать именно этот метод, а не inspect.iscoroutinefunction (если у вас возникнет такая потребность). Да, это немного сбивает с толку.
Однако, наш класс-декортатор имеет синхронную реализацию метода __call__ :
class FuncWrapper: def __call__(self, *args, **kwargs): return self.wrapped_call(*args, **kwargs)Эта реализация все еще корректно декорирует асинхронные функции, так как возвращает Awaitable объект при таком сценарии, однако распознается модулем asyncio как синхронная функция. Для того, чтобы избежать возможных ошибок, связанных с таким поведением, я рекомендую добавить в ваш класс поле _is_coroutine , которое позволит asyncio понять, что ваш класс — асинхронный декоратор.
from asyncio.coroutines import iscoroutinefunction, _is_coroutine class FuncWrapper(Generic[F_Spec, F_Return]): wrapped_call: Callable[F_Spec, F_Return] _is_coroutine: None def __init__(self, call: Callable[F_Spec, F_Return]) -> None: if not isinstance(call, FuncWrapper): if iscoroutinefunction(call): self._is_coroutine = _is_coroutine self.wrapped_call = call @FuncWrapper async def func() . assert iscoroutinefunction(func) is TrueНачиная с версии Python3.12 вместо поля _is_coroutine вы можете использовать _is_coroutine_marker , которая позволит модулю inspect понять, что ваша функция асинхронна.
Заключение
Я уверен, что в 99.9% случаев вам не понадобится мое решения с Class-based декоратором с переопределением new и прочей запретной магией. Однако, теперь вы знаете, как покрываются все возможные сценарии использования декоротаров: от самых простых, с исполнением кода до/после декорируемой функции, до самых сложных, когда вам необходимо хранить информацию обо всех примененных к функции декораторах.
И эти знания помогут вам выбрать то решение, которое необходимо именно для вашего сценария, а также легко и просто написать любое собственное.
А в качестве вишенки мы разобрались с тем, как правильно аннотировать декораторы в современном Python. Надеюсь, материал был для вас полезен.