[{"data":1,"prerenderedAt":2084},["ShallowReactive",2],{"navigation":3,"\u002Fblog\u002Fpython\u002Fst23":386,"\u002Fblog\u002Fpython\u002Fst23-surround":2079},[4],{"title":5,"path":6,"stem":7,"children":8,"page":114},"Blog","\u002Fblog","blog",[9,115,184,329],{"title":10,"path":11,"stem":12,"children":13,"page":114},"Ege","\u002Fblog\u002Fege","blog\u002Fege",[14,18,22,26,30,34,38,42,46,50,54,58,62,66,70,74,78,82,86,90,94,98,102,106,110],{"title":15,"path":16,"stem":17},"ЕГЭ Задание 1","\u002Fblog\u002Fege\u002Ftask1","blog\u002Fege\u002Ftask1",{"title":19,"path":20,"stem":21},"ЕГЭ Задание 10","\u002Fblog\u002Fege\u002Ftask10","blog\u002Fege\u002Ftask10",{"title":23,"path":24,"stem":25},"ЕГЭ Задание 11","\u002Fblog\u002Fege\u002Ftask11","blog\u002Fege\u002Ftask11",{"title":27,"path":28,"stem":29},"ЕГЭ Задание 12","\u002Fblog\u002Fege\u002Ftask12","blog\u002Fege\u002Ftask12",{"title":31,"path":32,"stem":33},"ЕГЭ Задание 13","\u002Fblog\u002Fege\u002Ftask13","blog\u002Fege\u002Ftask13",{"title":35,"path":36,"stem":37},"ЕГЭ Задание 14","\u002Fblog\u002Fege\u002Ftask14","blog\u002Fege\u002Ftask14",{"title":39,"path":40,"stem":41},"ЕГЭ Задание 15","\u002Fblog\u002Fege\u002Ftask15","blog\u002Fege\u002Ftask15",{"title":43,"path":44,"stem":45},"ЕГЭ Задание 16","\u002Fblog\u002Fege\u002Ftask16","blog\u002Fege\u002Ftask16",{"title":47,"path":48,"stem":49},"ЕГЭ Задание 17","\u002Fblog\u002Fege\u002Ftask17","blog\u002Fege\u002Ftask17",{"title":51,"path":52,"stem":53},"ЕГЭ Задание 18","\u002Fblog\u002Fege\u002Ftask18","blog\u002Fege\u002Ftask18",{"title":55,"path":56,"stem":57},"ЕГЭ Задание 19, 20, 21","\u002Fblog\u002Fege\u002Ftask19_20_21","blog\u002Fege\u002Ftask19_20_21",{"title":59,"path":60,"stem":61},"ЕГЭ Задание 2","\u002Fblog\u002Fege\u002Ftask2","blog\u002Fege\u002Ftask2",{"title":63,"path":64,"stem":65},"ЕГЭ Задание 22","\u002Fblog\u002Fege\u002Ftask22","blog\u002Fege\u002Ftask22",{"title":67,"path":68,"stem":69},"ЕГЭ Задание 23","\u002Fblog\u002Fege\u002Ftask23","blog\u002Fege\u002Ftask23",{"title":71,"path":72,"stem":73},"ЕГЭ Задание 24","\u002Fblog\u002Fege\u002Ftask24","blog\u002Fege\u002Ftask24",{"title":75,"path":76,"stem":77},"ЕГЭ Задание 25","\u002Fblog\u002Fege\u002Ftask25","blog\u002Fege\u002Ftask25",{"title":79,"path":80,"stem":81},"ЕГЭ Задание 26","\u002Fblog\u002Fege\u002Ftask26","blog\u002Fege\u002Ftask26",{"title":83,"path":84,"stem":85},"ЕГЭ Задание 27","\u002Fblog\u002Fege\u002Ftask27","blog\u002Fege\u002Ftask27",{"title":87,"path":88,"stem":89},"ЕГЭ Задание 3","\u002Fblog\u002Fege\u002Ftask3","blog\u002Fege\u002Ftask3",{"title":91,"path":92,"stem":93},"ЕГЭ Задание 4","\u002Fblog\u002Fege\u002Ftask4","blog\u002Fege\u002Ftask4",{"title":95,"path":96,"stem":97},"ЕГЭ Задание 5","\u002Fblog\u002Fege\u002Ftask5","blog\u002Fege\u002Ftask5",{"title":99,"path":100,"stem":101},"ЕГЭ Задание 6","\u002Fblog\u002Fege\u002Ftask6","blog\u002Fege\u002Ftask6",{"title":103,"path":104,"stem":105},"ЕГЭ Задание 7","\u002Fblog\u002Fege\u002Ftask7","blog\u002Fege\u002Ftask7",{"title":107,"path":108,"stem":109},"ЕГЭ Задание 8","\u002Fblog\u002Fege\u002Ftask8","blog\u002Fege\u002Ftask8",{"title":111,"path":112,"stem":113},"ЕГЭ Задание 9","\u002Fblog\u002Fege\u002Ftask9","blog\u002Fege\u002Ftask9",false,{"title":116,"path":117,"stem":118,"children":119,"page":114},"Oge","\u002Fblog\u002Foge","blog\u002Foge",[120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180],{"title":121,"path":122,"stem":123},"ОГЭ Задание 1","\u002Fblog\u002Foge\u002Ftask1","blog\u002Foge\u002Ftask1",{"title":125,"path":126,"stem":127},"ОГЭ Задание 10","\u002Fblog\u002Foge\u002Ftask10","blog\u002Foge\u002Ftask10",{"title":129,"path":130,"stem":131},"ОГЭ Задание 11","\u002Fblog\u002Foge\u002Ftask11","blog\u002Foge\u002Ftask11",{"title":133,"path":134,"stem":135},"ОГЭ Задание 12","\u002Fblog\u002Foge\u002Ftask12","blog\u002Foge\u002Ftask12",{"title":137,"path":138,"stem":139},"ОГЭ Задание 13","\u002Fblog\u002Foge\u002Ftask13","blog\u002Foge\u002Ftask13",{"title":141,"path":142,"stem":143},"ОГЭ Задание 14","\u002Fblog\u002Foge\u002Ftask14","blog\u002Foge\u002Ftask14",{"title":145,"path":146,"stem":147},"ОГЭ Задание 15","\u002Fblog\u002Foge\u002Ftask15","blog\u002Foge\u002Ftask15",{"title":149,"path":150,"stem":151},"ОГЭ Задание 16","\u002Fblog\u002Foge\u002Ftask16","blog\u002Foge\u002Ftask16",{"title":153,"path":154,"stem":155},"ОГЭ Задание 2","\u002Fblog\u002Foge\u002Ftask2","blog\u002Foge\u002Ftask2",{"title":157,"path":158,"stem":159},"ОГЭ Задание 3","\u002Fblog\u002Foge\u002Ftask3","blog\u002Foge\u002Ftask3",{"title":161,"path":162,"stem":163},"ОГЭ Задание 4","\u002Fblog\u002Foge\u002Ftask4","blog\u002Foge\u002Ftask4",{"title":165,"path":166,"stem":167},"ОГЭ Задание 5","\u002Fblog\u002Foge\u002Ftask5","blog\u002Foge\u002Ftask5",{"title":169,"path":170,"stem":171},"ОГЭ Задание 6","\u002Fblog\u002Foge\u002Ftask6","blog\u002Foge\u002Ftask6",{"title":173,"path":174,"stem":175},"ОГЭ Задание 7","\u002Fblog\u002Foge\u002Ftask7","blog\u002Foge\u002Ftask7",{"title":177,"path":178,"stem":179},"ОГЭ Задание 8","\u002Fblog\u002Foge\u002Ftask8","blog\u002Foge\u002Ftask8",{"title":181,"path":182,"stem":183},"ОГЭ Задание 9","\u002Fblog\u002Foge\u002Ftask9","blog\u002Foge\u002Ftask9",{"title":185,"path":186,"stem":187,"children":188,"page":114},"Python","\u002Fblog\u002Fpython","blog\u002Fpython",[189,193,197,201,205,209,213,217,221,225,229,233,237,241,245,249,253,257,261,265,269,273,277,281,285,289,293,297,301,305,309,313,317,321,325],{"title":190,"path":191,"stem":192},"Знакомство с синтаксисом","\u002Fblog\u002Fpython\u002Fst1","blog\u002Fpython\u002Fst1",{"title":194,"path":195,"stem":196},"Отладка","\u002Fblog\u002Fpython\u002Fst10","blog\u002Fpython\u002Fst10",{"title":198,"path":199,"stem":200},"Модули и пакеты","\u002Fblog\u002Fpython\u002Fst11","blog\u002Fpython\u002Fst11",{"title":202,"path":203,"stem":204},"Кортежи","\u002Fblog\u002Fpython\u002Fst12","blog\u002Fpython\u002Fst12",{"title":206,"path":207,"stem":208},"Знакомство со списками","\u002Fblog\u002Fpython\u002Fst13","blog\u002Fpython\u002Fst13",{"title":210,"path":211,"stem":212},"Списки и циклы","\u002Fblog\u002Fpython\u002Fst14","blog\u002Fpython\u002Fst14",{"title":214,"path":215,"stem":216},"Использование списков ч.1","\u002Fblog\u002Fpython\u002Fst15","blog\u002Fpython\u002Fst15",{"title":218,"path":219,"stem":220},"Использование списков ч.2","\u002Fblog\u002Fpython\u002Fst16","blog\u002Fpython\u002Fst16",{"title":222,"path":223,"stem":224},"Использование списков ч.3","\u002Fblog\u002Fpython\u002Fst17","blog\u002Fpython\u002Fst17",{"title":226,"path":227,"stem":228},"Словари","\u002Fblog\u002Fpython\u002Fst18","blog\u002Fpython\u002Fst18",{"title":230,"path":231,"stem":232},"Множества","\u002Fblog\u002Fpython\u002Fst19","blog\u002Fpython\u002Fst19",{"title":234,"path":235,"stem":236},"Переменные","\u002Fblog\u002Fpython\u002Fst2","blog\u002Fpython\u002Fst2",{"title":238,"path":239,"stem":240},"Хеш-таблицы","\u002Fblog\u002Fpython\u002Fst20","blog\u002Fpython\u002Fst20",{"title":242,"path":243,"stem":244},"Решето Эратосфена","\u002Fblog\u002Fpython\u002Fst21","blog\u002Fpython\u002Fst21",{"title":246,"path":247,"stem":248},"Длинная арифметика","\u002Fblog\u002Fpython\u002Fst22","blog\u002Fpython\u002Fst22",{"title":250,"path":251,"stem":252},"Декораторы функций","\u002Fblog\u002Fpython\u002Fst23","blog\u002Fpython\u002Fst23",{"title":254,"path":255,"stem":256},"Знакомство с алгоритмами","\u002Fblog\u002Fpython\u002Fst24","blog\u002Fpython\u002Fst24",{"title":258,"path":259,"stem":260},"Бинарный поиск – примеры задач","\u002Fblog\u002Fpython\u002Fst25","blog\u002Fpython\u002Fst25",{"title":262,"path":263,"stem":264},"Сортировка выбором","\u002Fblog\u002Fpython\u002Fst26","blog\u002Fpython\u002Fst26",{"title":266,"path":267,"stem":268},"Рекурсия и стек","\u002Fblog\u002Fpython\u002Fst27","blog\u002Fpython\u002Fst27",{"title":270,"path":271,"stem":272},"Быстрая сортировка","\u002Fblog\u002Fpython\u002Fst28","blog\u002Fpython\u002Fst28",{"title":274,"path":275,"stem":276},"Поиск в ширину","\u002Fblog\u002Fpython\u002Fst29","blog\u002Fpython\u002Fst29",{"title":278,"path":279,"stem":280},"Работа со строками","\u002Fblog\u002Fpython\u002Fst3","blog\u002Fpython\u002Fst3",{"title":282,"path":283,"stem":284},"Поиск в глубину","\u002Fblog\u002Fpython\u002Fst30","blog\u002Fpython\u002Fst30",{"title":286,"path":287,"stem":288},"Сбалансированные деревья","\u002Fblog\u002Fpython\u002Fst31","blog\u002Fpython\u002Fst31",{"title":290,"path":291,"stem":292},"Алгоритм Дейкстры","\u002Fblog\u002Fpython\u002Fst32","blog\u002Fpython\u002Fst32",{"title":294,"path":295,"stem":296},"Жадные алгоритмы","\u002Fblog\u002Fpython\u002Fst33","blog\u002Fpython\u002Fst33",{"title":298,"path":299,"stem":300},"Динамическое программирование","\u002Fblog\u002Fpython\u002Fst34","blog\u002Fpython\u002Fst34",{"title":302,"path":303,"stem":304},"Алгоритм k ближайших соседей","\u002Fblog\u002Fpython\u002Fst35","blog\u002Fpython\u002Fst35",{"title":306,"path":307,"stem":308},"Типы данных","\u002Fblog\u002Fpython\u002Fst4","blog\u002Fpython\u002Fst4",{"title":310,"path":311,"stem":312},"О функциях","\u002Fblog\u002Fpython\u002Fst5","blog\u002Fpython\u002Fst5",{"title":314,"path":315,"stem":316},"Свойства и методы","\u002Fblog\u002Fpython\u002Fst6","blog\u002Fpython\u002Fst6",{"title":318,"path":319,"stem":320},"Определение функций","\u002Fblog\u002Fpython\u002Fst7","blog\u002Fpython\u002Fst7",{"title":322,"path":323,"stem":324},"Логика","\u002Fblog\u002Fpython\u002Fst8","blog\u002Fpython\u002Fst8",{"title":326,"path":327,"stem":328},"Циклы","\u002Fblog\u002Fpython\u002Fst9","blog\u002Fpython\u002Fst9",{"title":330,"path":331,"stem":332,"children":333,"page":114},"Toi","\u002Fblog\u002Ftoi","blog\u002Ftoi",[334,338,342,346,350,354,358,362,366,370,374,378,382],{"title":335,"path":336,"stem":337},"Информация и информационные процессы","\u002Fblog\u002Ftoi\u002Fst1","blog\u002Ftoi\u002Fst1",{"title":339,"path":340,"stem":341},"Электронные таблицы","\u002Fblog\u002Ftoi\u002Fst10","blog\u002Ftoi\u002Fst10",{"title":343,"path":344,"stem":345},"Система, её свойства и компоненты. Моделирование","\u002Fblog\u002Ftoi\u002Fst11","blog\u002Ftoi\u002Fst11",{"title":347,"path":348,"stem":349},"Представление информации в компьютере","\u002Fblog\u002Ftoi\u002Fst12","blog\u002Ftoi\u002Fst12",{"title":351,"path":352,"stem":353},"Средства информационно-коммуникационных технологий. Файловая система","\u002Fblog\u002Ftoi\u002Fst13","blog\u002Ftoi\u002Fst13",{"title":355,"path":356,"stem":357},"Комбинаторика","\u002Fblog\u002Ftoi\u002Fst2","blog\u002Ftoi\u002Fst2",{"title":359,"path":360,"stem":361},"Адресация в интернете","\u002Fblog\u002Ftoi\u002Fst3","blog\u002Ftoi\u002Fst3",{"title":363,"path":364,"stem":365},"Измерение количества информации","\u002Fblog\u002Ftoi\u002Fst4","blog\u002Ftoi\u002Fst4",{"title":367,"path":368,"stem":369},"Системы счисления","\u002Fblog\u002Ftoi\u002Fst5","blog\u002Ftoi\u002Fst5",{"title":371,"path":372,"stem":373},"Диаграммы Эйлера — Венна","\u002Fblog\u002Ftoi\u002Fst6","blog\u002Ftoi\u002Fst6",{"title":375,"path":376,"stem":377},"Условие Фано","\u002Fblog\u002Ftoi\u002Fst7","blog\u002Ftoi\u002Fst7",{"title":379,"path":380,"stem":381},"Теория графов","\u002Fblog\u002Ftoi\u002Fst8","blog\u002Ftoi\u002Fst8",{"title":383,"path":384,"stem":385},"Алгебра логики","\u002Fblog\u002Ftoi\u002Fst9","blog\u002Ftoi\u002Fst9",{"id":387,"title":250,"author":388,"body":393,"date":2072,"description":2073,"extension":2074,"image":2075,"meta":2076,"minRead":720,"navigation":484,"num":812,"path":251,"seo":2077,"stem":252,"__hash__":2078},"python\u002Fblog\u002Fpython\u002Fst23.md",{"name":389,"avatar":390},"Штана Альберт Игоревич",{"src":391,"alt":392},"me.jpg","@ashtana",{"type":394,"value":395,"toc":2064},"minimark",[396,401,405,408,413,416,547,574,577,613,620,623,816,819,827,830,834,837,840,902,905,998,1008,1015,1074,1084,1261,1270,1280,1369,1372,1430,1433,1437,1440,1443,1526,1529,1611,1614,1768,1775,2039,2043,2046,2057,2060],[397,398,400],"h2",{"id":399},"декораторы","Декораторы",[402,403,404],"p",{},"В программировании часто возникают задачи, когда нужно добавить поведение к уже существующим функциям или классам. Например, логирование, проверку входных данных или замер времени выполнения функции. В таких случаях использование декораторов может значительно упростить решение задачи.",[402,406,407],{},"В этом уроке мы рассмотрим, что такое декораторы и как их использовать, чтобы добавлять дополнительную функциональность к существующим функциям.",[409,410,412],"h3",{"id":411},"что-такое-декораторы","Что такое декораторы",[402,414,415],{},"Ранее мы рассматривали как можно \"запомнить\" передаваемые значения в функцию с помощью замыканий. Напомним как выглядит синтаксис:",[417,418,423],"pre",{"className":419,"code":420,"language":421,"meta":422,"style":422},"language-python shiki shiki-themes github-light","def outer(arg1):\n    def inner(arg2):\n        return arg1 + arg2\n    return inner\n\ntwo_add = outer(2)\ntwo_add(1) # 3\ntwo_add(3) # 5\ntwo_add(5) # 7\n","python","",[424,425,426,443,455,470,479,486,505,521,534],"code",{"__ignoreMap":422},[427,428,431,435,439],"span",{"class":429,"line":430},"line",1,[427,432,434],{"class":433},"sD7c4","def",[427,436,438],{"class":437},"s7eDp"," outer",[427,440,442],{"class":441},"sgsFI","(arg1):\n",[427,444,446,449,452],{"class":429,"line":445},2,[427,447,448],{"class":433},"    def",[427,450,451],{"class":437}," inner",[427,453,454],{"class":441},"(arg2):\n",[427,456,458,461,464,467],{"class":429,"line":457},3,[427,459,460],{"class":433},"        return",[427,462,463],{"class":441}," arg1 ",[427,465,466],{"class":433},"+",[427,468,469],{"class":441}," arg2\n",[427,471,473,476],{"class":429,"line":472},4,[427,474,475],{"class":433},"    return",[427,477,478],{"class":441}," inner\n",[427,480,482],{"class":429,"line":481},5,[427,483,485],{"emptyLinePlaceholder":484},true,"\n",[427,487,489,492,495,498,502],{"class":429,"line":488},6,[427,490,491],{"class":441},"two_add ",[427,493,494],{"class":433},"=",[427,496,497],{"class":441}," outer(",[427,499,501],{"class":500},"sYu0t","2",[427,503,504],{"class":441},")\n",[427,506,508,511,514,517],{"class":429,"line":507},7,[427,509,510],{"class":441},"two_add(",[427,512,513],{"class":500},"1",[427,515,516],{"class":441},") ",[427,518,520],{"class":519},"sAwPA","# 3\n",[427,522,524,526,529,531],{"class":429,"line":523},8,[427,525,510],{"class":441},[427,527,528],{"class":500},"3",[427,530,516],{"class":441},[427,532,533],{"class":519},"# 5\n",[427,535,537,539,542,544],{"class":429,"line":536},9,[427,538,510],{"class":441},[427,540,541],{"class":500},"5",[427,543,516],{"class":441},[427,545,546],{"class":519},"# 7\n",[402,548,549,550,554,555,558,559,562,563,566,567,569,570,573],{},"В этом примере мы создаем функцию ",[551,552,553],"strong",{},"outer()",", которая принимает аргумент ",[551,556,557],{},"arg1"," и возвращает внутреннюю функцию ",[551,560,561],{},"inner()",". Внутренняя функция принимает аргумент ",[551,564,565],{},"arg2"," и возвращает сумму ",[551,568,557],{}," и ",[551,571,572],{},"agr2",".",[402,575,576],{},"Может запутать одновременное определение функции и возврат ее же. Но если мы вспомним, что определение функции это присваивание функции имени переменной, а также, что функции это данные, то пример можно представить как:",[417,578,580],{"className":419,"code":579,"language":421,"meta":422,"style":422},"def outer(arg1):\n    inner = lambda arg2: arg1 + arg2\n    return inner\n",[424,581,582,590,607],{"__ignoreMap":422},[427,583,584,586,588],{"class":429,"line":430},[427,585,434],{"class":433},[427,587,438],{"class":437},[427,589,442],{"class":441},[427,591,592,595,597,600,603,605],{"class":429,"line":445},[427,593,594],{"class":441},"    inner ",[427,596,494],{"class":433},[427,598,599],{"class":433}," lambda",[427,601,602],{"class":441}," arg2: arg1 ",[427,604,466],{"class":433},[427,606,469],{"class":441},[427,608,609,611],{"class":429,"line":457},[427,610,475],{"class":433},[427,612,478],{"class":441},[402,614,615,616,619],{},"Мы заменили именованную функцию лямбдой, и теперь присваивание ничем не отличается, как если бы мы присвоили переменной ",[551,617,618],{},"inner"," число или строку.",[402,621,622],{},"Но если функции всего лишь данные, то можно ли их также \"запоминать\" в замыканиях?",[417,624,626],{"className":419,"code":625,"language":421,"meta":422,"style":422},"def outer(func):\n    def inner(arg):\n        print('func = ', func)\n        print('arg = ', arg)\n        return func(arg)\n    return inner\n\ndef square(x):\n    return x ** 2\n\nprinter = outer(square)\n\nprinter(1) # 1\n# => func =  \u003Cfunction square at 0x75e04623a7a0>\n# => arg =  1\n\nprinter(2) # 4\n# => func =  \u003Cfunction square at 0x75e04623a7a0>\n# => arg =  2\n\nprinter(4) # 16\n# => func =  \u003Cfunction square at 0x75e04623a7a0>\n# => arg =  4\n",[424,627,628,637,646,661,673,680,686,690,700,713,718,729,734,747,753,759,764,776,781,787,792,805,810],{"__ignoreMap":422},[427,629,630,632,634],{"class":429,"line":430},[427,631,434],{"class":433},[427,633,438],{"class":437},[427,635,636],{"class":441},"(func):\n",[427,638,639,641,643],{"class":429,"line":445},[427,640,448],{"class":433},[427,642,451],{"class":437},[427,644,645],{"class":441},"(arg):\n",[427,647,648,651,654,658],{"class":429,"line":457},[427,649,650],{"class":500},"        print",[427,652,653],{"class":441},"(",[427,655,657],{"class":656},"sYBdl","'func = '",[427,659,660],{"class":441},", func)\n",[427,662,663,665,667,670],{"class":429,"line":472},[427,664,650],{"class":500},[427,666,653],{"class":441},[427,668,669],{"class":656},"'arg = '",[427,671,672],{"class":441},", arg)\n",[427,674,675,677],{"class":429,"line":481},[427,676,460],{"class":433},[427,678,679],{"class":441}," func(arg)\n",[427,681,682,684],{"class":429,"line":488},[427,683,475],{"class":433},[427,685,478],{"class":441},[427,687,688],{"class":429,"line":507},[427,689,485],{"emptyLinePlaceholder":484},[427,691,692,694,697],{"class":429,"line":523},[427,693,434],{"class":433},[427,695,696],{"class":437}," square",[427,698,699],{"class":441},"(x):\n",[427,701,702,704,707,710],{"class":429,"line":536},[427,703,475],{"class":433},[427,705,706],{"class":441}," x ",[427,708,709],{"class":433},"**",[427,711,712],{"class":500}," 2\n",[427,714,716],{"class":429,"line":715},10,[427,717,485],{"emptyLinePlaceholder":484},[427,719,721,724,726],{"class":429,"line":720},11,[427,722,723],{"class":441},"printer ",[427,725,494],{"class":433},[427,727,728],{"class":441}," outer(square)\n",[427,730,732],{"class":429,"line":731},12,[427,733,485],{"emptyLinePlaceholder":484},[427,735,737,740,742,744],{"class":429,"line":736},13,[427,738,739],{"class":441},"printer(",[427,741,513],{"class":500},[427,743,516],{"class":441},[427,745,746],{"class":519},"# 1\n",[427,748,750],{"class":429,"line":749},14,[427,751,752],{"class":519},"# => func =  \u003Cfunction square at 0x75e04623a7a0>\n",[427,754,756],{"class":429,"line":755},15,[427,757,758],{"class":519},"# => arg =  1\n",[427,760,762],{"class":429,"line":761},16,[427,763,485],{"emptyLinePlaceholder":484},[427,765,767,769,771,773],{"class":429,"line":766},17,[427,768,739],{"class":441},[427,770,501],{"class":500},[427,772,516],{"class":441},[427,774,775],{"class":519},"# 4\n",[427,777,779],{"class":429,"line":778},18,[427,780,752],{"class":519},[427,782,784],{"class":429,"line":783},19,[427,785,786],{"class":519},"# => arg =  2\n",[427,788,790],{"class":429,"line":789},20,[427,791,485],{"emptyLinePlaceholder":484},[427,793,795,797,800,802],{"class":429,"line":794},21,[427,796,739],{"class":441},[427,798,799],{"class":500},"4",[427,801,516],{"class":441},[427,803,804],{"class":519},"# 16\n",[427,806,808],{"class":429,"line":807},22,[427,809,752],{"class":519},[427,811,813],{"class":429,"line":812},23,[427,814,815],{"class":519},"# => arg =  4\n",[402,817,818],{},"Остановимся и разберем пример выше. В нем мы создаем замыкание, но теперь, вместо числа в замыкание передается функция. Внутренняя функция запомнила переданную в нее и может использовать внутри. Осталось лишь передать аргументы и вызвать замкнутую функцию с ними. В дополнение, мы смогли распечатать переданную функцию и ее аргументы, при этом код самой функции square() мы не меняли.",[402,820,821,822,826],{},"Функции выше называются декораторами. ",[823,824,825],"em",{},"Декораторы в Python"," — это функции, которые принимают другую функцию в качестве аргумента, добавляют к ней дополнительную функциональность и возвращают функцию с измененным поведением. Декораторы позволяют изменять поведение функций и классов с помощью добавления или изменения их функциональности без изменения самого кода.",[402,828,829],{},"Также, как вы могли заметить, декораторы это частный случай функции высшего порядка (принимаем функцию) и использования замыкания вместе.",[409,831,833],{"id":832},"использование-декораторов","Использование декораторов",[402,835,836],{},"Декораторы используются в Python повсеместно: для логирования, кеширования, добавления нового функционала, используются в тестовых и веб-фреймворках.",[402,838,839],{},"Предположим, что у нас есть функция, которая суммирует числа:",[417,841,843],{"className":419,"code":842,"language":421,"meta":422,"style":422},"def sum(*nums):\n    result = 0\n    for num in nums:\n        result += num\n    return result\n",[424,844,845,860,870,884,895],{"__ignoreMap":422},[427,846,847,849,852,854,857],{"class":429,"line":430},[427,848,434],{"class":433},[427,850,851],{"class":500}," sum",[427,853,653],{"class":441},[427,855,856],{"class":433},"*",[427,858,859],{"class":441},"nums):\n",[427,861,862,865,867],{"class":429,"line":445},[427,863,864],{"class":441},"    result ",[427,866,494],{"class":433},[427,868,869],{"class":500}," 0\n",[427,871,872,875,878,881],{"class":429,"line":457},[427,873,874],{"class":433},"    for",[427,876,877],{"class":441}," num ",[427,879,880],{"class":433},"in",[427,882,883],{"class":441}," nums:\n",[427,885,886,889,892],{"class":429,"line":472},[427,887,888],{"class":441},"        result ",[427,890,891],{"class":433},"+=",[427,893,894],{"class":441}," num\n",[427,896,897,899],{"class":429,"line":481},[427,898,475],{"class":433},[427,900,901],{"class":441}," result\n",[402,903,904],{},"Создадим декоратор, который добавит к этой функции функциональность для отладки:",[417,906,908],{"className":419,"code":907,"language":421,"meta":422,"style":422},"def debug_decorator(func):\n    # внутреннюю функцию принято называть wrapper - обертка\n    def wrapper(*args, **kwargs):\n        print(\"Args:\", args, kwargs)\n        result = func(*args, **kwargs)\n        print(\"Result:\", result)\n        return result\n    return wrapper\n",[424,909,910,919,924,943,955,973,985,991],{"__ignoreMap":422},[427,911,912,914,917],{"class":429,"line":430},[427,913,434],{"class":433},[427,915,916],{"class":437}," debug_decorator",[427,918,636],{"class":441},[427,920,921],{"class":429,"line":445},[427,922,923],{"class":519},"    # внутреннюю функцию принято называть wrapper - обертка\n",[427,925,926,928,931,933,935,938,940],{"class":429,"line":457},[427,927,448],{"class":433},[427,929,930],{"class":437}," wrapper",[427,932,653],{"class":441},[427,934,856],{"class":433},[427,936,937],{"class":441},"args, ",[427,939,709],{"class":433},[427,941,942],{"class":441},"kwargs):\n",[427,944,945,947,949,952],{"class":429,"line":472},[427,946,650],{"class":500},[427,948,653],{"class":441},[427,950,951],{"class":656},"\"Args:\"",[427,953,954],{"class":441},", args, kwargs)\n",[427,956,957,959,961,964,966,968,970],{"class":429,"line":481},[427,958,888],{"class":441},[427,960,494],{"class":433},[427,962,963],{"class":441}," func(",[427,965,856],{"class":433},[427,967,937],{"class":441},[427,969,709],{"class":433},[427,971,972],{"class":441},"kwargs)\n",[427,974,975,977,979,982],{"class":429,"line":488},[427,976,650],{"class":500},[427,978,653],{"class":441},[427,980,981],{"class":656},"\"Result:\"",[427,983,984],{"class":441},", result)\n",[427,986,987,989],{"class":429,"line":507},[427,988,460],{"class":433},[427,990,901],{"class":441},[427,992,993,995],{"class":429,"line":523},[427,994,475],{"class":433},[427,996,997],{"class":441}," wrapper\n",[402,999,1000,1001,569,1004,1007],{},"Этот декоратор принимает функцию в качестве аргумента и возвращает новую функцию-обертку, которая добавляет отладочные сообщения в процесс выполнения исходной функции. Заметьте, что внутренняя функция принимает сразу все аргументы с помощью ",[551,1002,1003],{},"*args",[551,1005,1006],{},"**kwargs",". Так мы можем создавать \"всеядные\" обертки.",[402,1009,1010,1011,1014],{},"Применим этот декоратор к функции ",[551,1012,1013],{},"sum()",":",[417,1016,1018],{"className":419,"code":1017,"language":421,"meta":422,"style":422},"debugged_sum = debug_decorator(sum)\n\ndebugged_sum(1, 2, 3) # 6\n\n# => Args: (1, 2, 3) {}\n# => Result: 6\n",[424,1019,1020,1035,1039,1060,1064,1069],{"__ignoreMap":422},[427,1021,1022,1025,1027,1030,1033],{"class":429,"line":430},[427,1023,1024],{"class":441},"debugged_sum ",[427,1026,494],{"class":433},[427,1028,1029],{"class":441}," debug_decorator(",[427,1031,1032],{"class":500},"sum",[427,1034,504],{"class":441},[427,1036,1037],{"class":429,"line":445},[427,1038,485],{"emptyLinePlaceholder":484},[427,1040,1041,1044,1046,1049,1051,1053,1055,1057],{"class":429,"line":457},[427,1042,1043],{"class":441},"debugged_sum(",[427,1045,513],{"class":500},[427,1047,1048],{"class":441},", ",[427,1050,501],{"class":500},[427,1052,1048],{"class":441},[427,1054,528],{"class":500},[427,1056,516],{"class":441},[427,1058,1059],{"class":519},"# 6\n",[427,1061,1062],{"class":429,"line":472},[427,1063,485],{"emptyLinePlaceholder":484},[427,1065,1066],{"class":429,"line":481},[427,1067,1068],{"class":519},"# => Args: (1, 2, 3) {}\n",[427,1070,1071],{"class":429,"line":488},[427,1072,1073],{"class":519},"# => Result: 6\n",[402,1075,1076,1077,1080,1081,1083],{},"Проблема в коде выше, что теперь функция называется ",[551,1078,1079],{},"debugged_sum()",", и нужно будет изменить весь код, что использовал ",[551,1082,1013],{},". Но ведь имя функции это всего лишь имя переменной, и мы можем перезаписать новую, декорированную функцию в ту же переменную.",[417,1085,1087],{"className":419,"code":1086,"language":421,"meta":422,"style":422},"sum = debug_decorator(sum)\n\nsum(1, 2, 3) # 6\n# => Args: (1, 2, 3) {}\n# => Result: 6\n\ndef sum_odd_numbers(nums):\n    odd = []\n    for num in nums:\n        if num % 2 != 0:\n            odd.append(num)\n    return sum(*odd)\n\nnumbers = [1, 2, 3, 4, 5]\nsum_odd_numbers(numbers) # 9\n# => Args: (1, 3, 5) {}\n# => Result: 9\n",[424,1088,1089,1102,1106,1126,1130,1134,1138,1148,1158,1168,1190,1195,1208,1212,1243,1251,1256],{"__ignoreMap":422},[427,1090,1091,1093,1096,1098,1100],{"class":429,"line":430},[427,1092,1032],{"class":500},[427,1094,1095],{"class":433}," =",[427,1097,1029],{"class":441},[427,1099,1032],{"class":500},[427,1101,504],{"class":441},[427,1103,1104],{"class":429,"line":445},[427,1105,485],{"emptyLinePlaceholder":484},[427,1107,1108,1110,1112,1114,1116,1118,1120,1122,1124],{"class":429,"line":457},[427,1109,1032],{"class":500},[427,1111,653],{"class":441},[427,1113,513],{"class":500},[427,1115,1048],{"class":441},[427,1117,501],{"class":500},[427,1119,1048],{"class":441},[427,1121,528],{"class":500},[427,1123,516],{"class":441},[427,1125,1059],{"class":519},[427,1127,1128],{"class":429,"line":472},[427,1129,1068],{"class":519},[427,1131,1132],{"class":429,"line":481},[427,1133,1073],{"class":519},[427,1135,1136],{"class":429,"line":488},[427,1137,485],{"emptyLinePlaceholder":484},[427,1139,1140,1142,1145],{"class":429,"line":507},[427,1141,434],{"class":433},[427,1143,1144],{"class":437}," sum_odd_numbers",[427,1146,1147],{"class":441},"(nums):\n",[427,1149,1150,1153,1155],{"class":429,"line":523},[427,1151,1152],{"class":441},"    odd ",[427,1154,494],{"class":433},[427,1156,1157],{"class":441}," []\n",[427,1159,1160,1162,1164,1166],{"class":429,"line":536},[427,1161,874],{"class":433},[427,1163,877],{"class":441},[427,1165,880],{"class":433},[427,1167,883],{"class":441},[427,1169,1170,1173,1175,1178,1181,1184,1187],{"class":429,"line":715},[427,1171,1172],{"class":433},"        if",[427,1174,877],{"class":441},[427,1176,1177],{"class":433},"%",[427,1179,1180],{"class":500}," 2",[427,1182,1183],{"class":433}," !=",[427,1185,1186],{"class":500}," 0",[427,1188,1189],{"class":441},":\n",[427,1191,1192],{"class":429,"line":720},[427,1193,1194],{"class":441},"            odd.append(num)\n",[427,1196,1197,1199,1201,1203,1205],{"class":429,"line":731},[427,1198,475],{"class":433},[427,1200,851],{"class":500},[427,1202,653],{"class":441},[427,1204,856],{"class":433},[427,1206,1207],{"class":441},"odd)\n",[427,1209,1210],{"class":429,"line":736},[427,1211,485],{"emptyLinePlaceholder":484},[427,1213,1214,1217,1219,1222,1224,1226,1228,1230,1232,1234,1236,1238,1240],{"class":429,"line":749},[427,1215,1216],{"class":441},"numbers ",[427,1218,494],{"class":433},[427,1220,1221],{"class":441}," [",[427,1223,513],{"class":500},[427,1225,1048],{"class":441},[427,1227,501],{"class":500},[427,1229,1048],{"class":441},[427,1231,528],{"class":500},[427,1233,1048],{"class":441},[427,1235,799],{"class":500},[427,1237,1048],{"class":441},[427,1239,541],{"class":500},[427,1241,1242],{"class":441},"]\n",[427,1244,1245,1248],{"class":429,"line":755},[427,1246,1247],{"class":441},"sum_odd_numbers(numbers) ",[427,1249,1250],{"class":519},"# 9\n",[427,1252,1253],{"class":429,"line":761},[427,1254,1255],{"class":519},"# => Args: (1, 3, 5) {}\n",[427,1257,1258],{"class":429,"line":766},[427,1259,1260],{"class":519},"# => Result: 9\n",[402,1262,1263,1264,1266,1267,1269],{},"Теперь функция ",[551,1265,1013],{}," будет выполняться с дополнительными отладочными сообщениями. А также весь код, использующий функцию ",[551,1268,1013],{}," будет использовать новую функцию.",[402,1271,1272,1273,1276,1277],{},"Чтобы не добавлять запись вида ",[551,1274,1275],{},"func = decorator(func)"," каждый раз, в Python добавили синтаксический сахар - ",[551,1278,1279],{},"@decorator",[417,1281,1283],{"className":419,"code":1282,"language":421,"meta":422,"style":422},"# декоратор нужно добавить над определением функции, которую хотим декорировать\n@debug_decorator\ndef sum(*nums):\n    result = 0\n    for num in nums:\n        result += num\n    return result\n\nsum(1, 2) # 3\n# => Args: (1, 2) {}\n# => Result: 3\n",[424,1284,1285,1290,1295,1307,1315,1325,1333,1339,1343,1359,1364],{"__ignoreMap":422},[427,1286,1287],{"class":429,"line":430},[427,1288,1289],{"class":519},"# декоратор нужно добавить над определением функции, которую хотим декорировать\n",[427,1291,1292],{"class":429,"line":445},[427,1293,1294],{"class":437},"@debug_decorator\n",[427,1296,1297,1299,1301,1303,1305],{"class":429,"line":457},[427,1298,434],{"class":433},[427,1300,851],{"class":500},[427,1302,653],{"class":441},[427,1304,856],{"class":433},[427,1306,859],{"class":441},[427,1308,1309,1311,1313],{"class":429,"line":472},[427,1310,864],{"class":441},[427,1312,494],{"class":433},[427,1314,869],{"class":500},[427,1316,1317,1319,1321,1323],{"class":429,"line":481},[427,1318,874],{"class":433},[427,1320,877],{"class":441},[427,1322,880],{"class":433},[427,1324,883],{"class":441},[427,1326,1327,1329,1331],{"class":429,"line":488},[427,1328,888],{"class":441},[427,1330,891],{"class":433},[427,1332,894],{"class":441},[427,1334,1335,1337],{"class":429,"line":507},[427,1336,475],{"class":433},[427,1338,901],{"class":441},[427,1340,1341],{"class":429,"line":523},[427,1342,485],{"emptyLinePlaceholder":484},[427,1344,1345,1347,1349,1351,1353,1355,1357],{"class":429,"line":536},[427,1346,1032],{"class":500},[427,1348,653],{"class":441},[427,1350,513],{"class":500},[427,1352,1048],{"class":441},[427,1354,501],{"class":500},[427,1356,516],{"class":441},[427,1358,520],{"class":519},[427,1360,1361],{"class":429,"line":715},[427,1362,1363],{"class":519},"# => Args: (1, 2) {}\n",[427,1365,1366],{"class":429,"line":720},[427,1367,1368],{"class":519},"# => Result: 3\n",[402,1370,1371],{},"Также мы можем создавать несколько декораторов для одной функции, которые будут применяться последовательно:",[417,1373,1375],{"className":419,"code":1374,"language":421,"meta":422,"style":422},"@debug_decorator\n@time_decorator\ndef sum(*nums):\n    result = 0\n    for num in nums:\n        result += num\n    return result\n",[424,1376,1377,1381,1386,1398,1406,1416,1424],{"__ignoreMap":422},[427,1378,1379],{"class":429,"line":430},[427,1380,1294],{"class":437},[427,1382,1383],{"class":429,"line":445},[427,1384,1385],{"class":437},"@time_decorator\n",[427,1387,1388,1390,1392,1394,1396],{"class":429,"line":457},[427,1389,434],{"class":433},[427,1391,851],{"class":500},[427,1393,653],{"class":441},[427,1395,856],{"class":433},[427,1397,859],{"class":441},[427,1399,1400,1402,1404],{"class":429,"line":472},[427,1401,864],{"class":441},[427,1403,494],{"class":433},[427,1405,869],{"class":500},[427,1407,1408,1410,1412,1414],{"class":429,"line":481},[427,1409,874],{"class":433},[427,1411,877],{"class":441},[427,1413,880],{"class":433},[427,1415,883],{"class":441},[427,1417,1418,1420,1422],{"class":429,"line":488},[427,1419,888],{"class":441},[427,1421,891],{"class":433},[427,1423,894],{"class":441},[427,1425,1426,1428],{"class":429,"line":507},[427,1427,475],{"class":433},[427,1429,901],{"class":441},[402,1431,1432],{},"В этом примере сначала применится декоратор времени выполнения, а затем отладочный декоратор.",[409,1434,1436],{"id":1435},"декораторы-с-параметрами","Декораторы с параметрами",[402,1438,1439],{},"Что если мы хотели бы вызывать обернутую функцию с разными настройками? Для этого нам понадобятся декораторы с параметрами.",[402,1441,1442],{},"Общий синтаксис декоратора с параметрами выглядит так:",[417,1444,1446],{"className":419,"code":1445,"language":421,"meta":422,"style":422},"def decorator_with_params(param1, param2, ...):\n    def actual_decorator(func):\n        def wrapper(*args, **kwargs):\n            # Здесь можем использовать param1, param2, ...\n            result = func(*args, **kwargs)\n            return result\n        return wrapper\n    return actual_decorator\n",[424,1447,1448,1458,1467,1484,1489,1506,1513,1519],{"__ignoreMap":422},[427,1449,1450,1452,1455],{"class":429,"line":430},[427,1451,434],{"class":433},[427,1453,1454],{"class":437}," decorator_with_params",[427,1456,1457],{"class":441},"(param1, param2, ...):\n",[427,1459,1460,1462,1465],{"class":429,"line":445},[427,1461,448],{"class":433},[427,1463,1464],{"class":437}," actual_decorator",[427,1466,636],{"class":441},[427,1468,1469,1472,1474,1476,1478,1480,1482],{"class":429,"line":457},[427,1470,1471],{"class":433},"        def",[427,1473,930],{"class":437},[427,1475,653],{"class":441},[427,1477,856],{"class":433},[427,1479,937],{"class":441},[427,1481,709],{"class":433},[427,1483,942],{"class":441},[427,1485,1486],{"class":429,"line":472},[427,1487,1488],{"class":519},"            # Здесь можем использовать param1, param2, ...\n",[427,1490,1491,1494,1496,1498,1500,1502,1504],{"class":429,"line":481},[427,1492,1493],{"class":441},"            result ",[427,1495,494],{"class":433},[427,1497,963],{"class":441},[427,1499,856],{"class":433},[427,1501,937],{"class":441},[427,1503,709],{"class":433},[427,1505,972],{"class":441},[427,1507,1508,1511],{"class":429,"line":488},[427,1509,1510],{"class":433},"            return",[427,1512,901],{"class":441},[427,1514,1515,1517],{"class":429,"line":507},[427,1516,460],{"class":433},[427,1518,997],{"class":441},[427,1520,1521,1523],{"class":429,"line":523},[427,1522,475],{"class":433},[427,1524,1525],{"class":441}," actual_decorator\n",[402,1527,1528],{},"К обычному декоратору мы добавляем еще один слой с параметрами. И, конечно, в качестве параметров мы можем передавать другие функции:",[417,1530,1532],{"className":419,"code":1531,"language":421,"meta":422,"style":422},"def filter_by(key):\n    def inner(func):\n        def wrapper(*args):\n            args = key(args)\n            print('filtered args = ', args)\n            return func(*args)\n        return wrapper\n    return inner\n",[424,1533,1534,1544,1552,1565,1575,1588,1599,1605],{"__ignoreMap":422},[427,1535,1536,1538,1541],{"class":429,"line":430},[427,1537,434],{"class":433},[427,1539,1540],{"class":437}," filter_by",[427,1542,1543],{"class":441},"(key):\n",[427,1545,1546,1548,1550],{"class":429,"line":445},[427,1547,448],{"class":433},[427,1549,451],{"class":437},[427,1551,636],{"class":441},[427,1553,1554,1556,1558,1560,1562],{"class":429,"line":457},[427,1555,1471],{"class":433},[427,1557,930],{"class":437},[427,1559,653],{"class":441},[427,1561,856],{"class":433},[427,1563,1564],{"class":441},"args):\n",[427,1566,1567,1570,1572],{"class":429,"line":472},[427,1568,1569],{"class":441},"            args ",[427,1571,494],{"class":433},[427,1573,1574],{"class":441}," key(args)\n",[427,1576,1577,1580,1582,1585],{"class":429,"line":481},[427,1578,1579],{"class":500},"            print",[427,1581,653],{"class":441},[427,1583,1584],{"class":656},"'filtered args = '",[427,1586,1587],{"class":441},", args)\n",[427,1589,1590,1592,1594,1596],{"class":429,"line":488},[427,1591,1510],{"class":433},[427,1593,963],{"class":441},[427,1595,856],{"class":433},[427,1597,1598],{"class":441},"args)\n",[427,1600,1601,1603],{"class":429,"line":507},[427,1602,460],{"class":433},[427,1604,997],{"class":441},[427,1606,1607,1609],{"class":429,"line":523},[427,1608,475],{"class":433},[427,1610,478],{"class":441},[402,1612,1613],{},"И даже функции с собственными параметрами, используя замыкания:",[417,1615,1617],{"className":419,"code":1616,"language":421,"meta":422,"style":422},"def odd(numbers):\n    result = []\n    for num in numbers:\n        if num % 2 == 1:\n            result.append(num)\n    return result\n\n@filter_by(odd)\ndef sum(*nums):\n    result = 0\n    for num in nums:\n        result += num\n    return result\n\nsum(3, 4, 5, 6) # 8\n# => filtered args =  [3, 5]\n",[424,1618,1619,1629,1637,1648,1666,1671,1677,1681,1689,1701,1709,1719,1727,1733,1737,1763],{"__ignoreMap":422},[427,1620,1621,1623,1626],{"class":429,"line":430},[427,1622,434],{"class":433},[427,1624,1625],{"class":437}," odd",[427,1627,1628],{"class":441},"(numbers):\n",[427,1630,1631,1633,1635],{"class":429,"line":445},[427,1632,864],{"class":441},[427,1634,494],{"class":433},[427,1636,1157],{"class":441},[427,1638,1639,1641,1643,1645],{"class":429,"line":457},[427,1640,874],{"class":433},[427,1642,877],{"class":441},[427,1644,880],{"class":433},[427,1646,1647],{"class":441}," numbers:\n",[427,1649,1650,1652,1654,1656,1658,1661,1664],{"class":429,"line":472},[427,1651,1172],{"class":433},[427,1653,877],{"class":441},[427,1655,1177],{"class":433},[427,1657,1180],{"class":500},[427,1659,1660],{"class":433}," ==",[427,1662,1663],{"class":500}," 1",[427,1665,1189],{"class":441},[427,1667,1668],{"class":429,"line":481},[427,1669,1670],{"class":441},"            result.append(num)\n",[427,1672,1673,1675],{"class":429,"line":488},[427,1674,475],{"class":433},[427,1676,901],{"class":441},[427,1678,1679],{"class":429,"line":507},[427,1680,485],{"emptyLinePlaceholder":484},[427,1682,1683,1686],{"class":429,"line":523},[427,1684,1685],{"class":437},"@filter_by",[427,1687,1688],{"class":441},"(odd)\n",[427,1690,1691,1693,1695,1697,1699],{"class":429,"line":536},[427,1692,434],{"class":433},[427,1694,851],{"class":500},[427,1696,653],{"class":441},[427,1698,856],{"class":433},[427,1700,859],{"class":441},[427,1702,1703,1705,1707],{"class":429,"line":715},[427,1704,864],{"class":441},[427,1706,494],{"class":433},[427,1708,869],{"class":500},[427,1710,1711,1713,1715,1717],{"class":429,"line":720},[427,1712,874],{"class":433},[427,1714,877],{"class":441},[427,1716,880],{"class":433},[427,1718,883],{"class":441},[427,1720,1721,1723,1725],{"class":429,"line":731},[427,1722,888],{"class":441},[427,1724,891],{"class":433},[427,1726,894],{"class":441},[427,1728,1729,1731],{"class":429,"line":736},[427,1730,475],{"class":433},[427,1732,901],{"class":441},[427,1734,1735],{"class":429,"line":749},[427,1736,485],{"emptyLinePlaceholder":484},[427,1738,1739,1741,1743,1745,1747,1749,1751,1753,1755,1758,1760],{"class":429,"line":755},[427,1740,1032],{"class":500},[427,1742,653],{"class":441},[427,1744,528],{"class":500},[427,1746,1048],{"class":441},[427,1748,799],{"class":500},[427,1750,1048],{"class":441},[427,1752,541],{"class":500},[427,1754,1048],{"class":441},[427,1756,1757],{"class":500},"6",[427,1759,516],{"class":441},[427,1761,1762],{"class":519},"# 8\n",[427,1764,1765],{"class":429,"line":761},[427,1766,1767],{"class":519},"# => filtered args =  [3, 5]\n",[402,1769,1770,1771,1774],{},"Декоратор ",[551,1772,1773],{},"filter_by()"," принимает функцию фильтрации key(), затем применяет ее к аргументам обернутой функции, и вызывает обернутую функцию с новыми аргументами.",[417,1776,1778],{"className":419,"code":1777,"language":421,"meta":422,"style":422},"def less_than(max):\n    def inner(numbers):\n        result = []\n        for num in numbers:\n            if num \u003C max:\n                result.append(num)\n        return result\n    return inner\n\n@filter_by(less_than(5))\ndef sum(*nums):\n    result = 0\n    for num in nums:\n        result += num\n    return result\n\nsum(3, 4, 5, 6) # 7\n# => filtered args =  [3, 4]\n\n@filter_by(less_than(3))\ndef sum(*nums):\n    result = 0\n    for num in nums:\n        result += num\n    return result\n\nsum(3, 4, 5, 6) # 0\n# => filtered args =  []\n",[424,1779,1780,1790,1798,1806,1817,1832,1837,1843,1849,1853,1865,1877,1885,1895,1903,1909,1913,1937,1942,1946,1956,1968,1976,1986,1995,2002,2007,2033],{"__ignoreMap":422},[427,1781,1782,1784,1787],{"class":429,"line":430},[427,1783,434],{"class":433},[427,1785,1786],{"class":437}," less_than",[427,1788,1789],{"class":441},"(max):\n",[427,1791,1792,1794,1796],{"class":429,"line":445},[427,1793,448],{"class":433},[427,1795,451],{"class":437},[427,1797,1628],{"class":441},[427,1799,1800,1802,1804],{"class":429,"line":457},[427,1801,888],{"class":441},[427,1803,494],{"class":433},[427,1805,1157],{"class":441},[427,1807,1808,1811,1813,1815],{"class":429,"line":472},[427,1809,1810],{"class":433},"        for",[427,1812,877],{"class":441},[427,1814,880],{"class":433},[427,1816,1647],{"class":441},[427,1818,1819,1822,1824,1827,1830],{"class":429,"line":481},[427,1820,1821],{"class":433},"            if",[427,1823,877],{"class":441},[427,1825,1826],{"class":433},"\u003C",[427,1828,1829],{"class":500}," max",[427,1831,1189],{"class":441},[427,1833,1834],{"class":429,"line":488},[427,1835,1836],{"class":441},"                result.append(num)\n",[427,1838,1839,1841],{"class":429,"line":507},[427,1840,460],{"class":433},[427,1842,901],{"class":441},[427,1844,1845,1847],{"class":429,"line":523},[427,1846,475],{"class":433},[427,1848,478],{"class":441},[427,1850,1851],{"class":429,"line":536},[427,1852,485],{"emptyLinePlaceholder":484},[427,1854,1855,1857,1860,1862],{"class":429,"line":715},[427,1856,1685],{"class":437},[427,1858,1859],{"class":441},"(less_than(",[427,1861,541],{"class":500},[427,1863,1864],{"class":441},"))\n",[427,1866,1867,1869,1871,1873,1875],{"class":429,"line":720},[427,1868,434],{"class":433},[427,1870,851],{"class":500},[427,1872,653],{"class":441},[427,1874,856],{"class":433},[427,1876,859],{"class":441},[427,1878,1879,1881,1883],{"class":429,"line":731},[427,1880,864],{"class":441},[427,1882,494],{"class":433},[427,1884,869],{"class":500},[427,1886,1887,1889,1891,1893],{"class":429,"line":736},[427,1888,874],{"class":433},[427,1890,877],{"class":441},[427,1892,880],{"class":433},[427,1894,883],{"class":441},[427,1896,1897,1899,1901],{"class":429,"line":749},[427,1898,888],{"class":441},[427,1900,891],{"class":433},[427,1902,894],{"class":441},[427,1904,1905,1907],{"class":429,"line":755},[427,1906,475],{"class":433},[427,1908,901],{"class":441},[427,1910,1911],{"class":429,"line":761},[427,1912,485],{"emptyLinePlaceholder":484},[427,1914,1915,1917,1919,1921,1923,1925,1927,1929,1931,1933,1935],{"class":429,"line":766},[427,1916,1032],{"class":500},[427,1918,653],{"class":441},[427,1920,528],{"class":500},[427,1922,1048],{"class":441},[427,1924,799],{"class":500},[427,1926,1048],{"class":441},[427,1928,541],{"class":500},[427,1930,1048],{"class":441},[427,1932,1757],{"class":500},[427,1934,516],{"class":441},[427,1936,546],{"class":519},[427,1938,1939],{"class":429,"line":778},[427,1940,1941],{"class":519},"# => filtered args =  [3, 4]\n",[427,1943,1944],{"class":429,"line":783},[427,1945,485],{"emptyLinePlaceholder":484},[427,1947,1948,1950,1952,1954],{"class":429,"line":789},[427,1949,1685],{"class":437},[427,1951,1859],{"class":441},[427,1953,528],{"class":500},[427,1955,1864],{"class":441},[427,1957,1958,1960,1962,1964,1966],{"class":429,"line":794},[427,1959,434],{"class":433},[427,1961,851],{"class":500},[427,1963,653],{"class":441},[427,1965,856],{"class":433},[427,1967,859],{"class":441},[427,1969,1970,1972,1974],{"class":429,"line":807},[427,1971,864],{"class":441},[427,1973,494],{"class":433},[427,1975,869],{"class":500},[427,1977,1978,1980,1982,1984],{"class":429,"line":812},[427,1979,874],{"class":433},[427,1981,877],{"class":441},[427,1983,880],{"class":433},[427,1985,883],{"class":441},[427,1987,1989,1991,1993],{"class":429,"line":1988},24,[427,1990,888],{"class":441},[427,1992,891],{"class":433},[427,1994,894],{"class":441},[427,1996,1998,2000],{"class":429,"line":1997},25,[427,1999,475],{"class":433},[427,2001,901],{"class":441},[427,2003,2005],{"class":429,"line":2004},26,[427,2006,485],{"emptyLinePlaceholder":484},[427,2008,2010,2012,2014,2016,2018,2020,2022,2024,2026,2028,2030],{"class":429,"line":2009},27,[427,2011,1032],{"class":500},[427,2013,653],{"class":441},[427,2015,528],{"class":500},[427,2017,1048],{"class":441},[427,2019,799],{"class":500},[427,2021,1048],{"class":441},[427,2023,541],{"class":500},[427,2025,1048],{"class":441},[427,2027,1757],{"class":500},[427,2029,516],{"class":441},[427,2031,2032],{"class":519},"# 0\n",[427,2034,2036],{"class":429,"line":2035},28,[427,2037,2038],{"class":519},"# => filtered args =  []\n",[409,2040,2042],{"id":2041},"выводы","Выводы",[402,2044,2045],{},"Мы изучили декораторы, мощный механизм для расширения функций.\nСуществует большое количество готовых декораторов, доступных в стандартной библиотеке Python и других библиотеках.\nНекоторые из них позволяют кэшировать результаты функций, обеспечивать авторизацию и безопасность, профилировать код, проверять типы данных и многое другое.",[402,2047,2048,2049,2052,2053,2056],{},"Попробуйте сами запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает. Для этого в ячейке с кодом нажмите клавиши на клавиатуре ",[551,2050,2051],{},"Shift+Enter"," или запустите код через ",[551,2054,2055],{},"кнопку Run"," по значку ▶.",[2058,2059],"jypiter",{},[2061,2062,2063],"style",{},"html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}",{"title":422,"searchDepth":445,"depth":481,"links":2065},[2066],{"id":399,"depth":445,"text":400,"children":2067},[2068,2069,2070,2071],{"id":411,"depth":457,"text":412},{"id":832,"depth":457,"text":833},{"id":1435,"depth":457,"text":1436},{"id":2041,"depth":457,"text":2042},"2024-12-04","Что такое декораторы функций и как их использовать","md","images\u002Fblog\u002Fpython\u002Fst23\u002Fimg.png",{},{"title":250,"description":2073},"i-rdfcRzc3i_lrY-JV7S1UKNvc-CBHwE5OX3bTNHnTI",[2080,2082],{"title":246,"path":247,"stem":248,"description":2081,"children":-1},"Многоразрядные целые числа. Задачи длинной арифметики",{"title":254,"path":255,"stem":256,"description":2083,"children":-1},"Введение. Реализация алгоритма бинарного поиска. Время выполнения алгоритмов",1780737509730]