Знак лямбды: Лямбда-выражения — Справочник по C# | Microsoft Docs

Содержание

Греческий алфавит

Греческий алфавит

A α alpha альфа
B β beta бета
Г γ gamma гамма
Δ δ delta дельта
E ε epsilon эпсилон
Z ζ zeta дзета
H η eta эта
Θ θ theta тета
I
ί
iota йота
K κ kappa каппа
Λ λ lambda ламбда
M mu мю
N nu ню
Ξ ξ xi кси
O o omicron омикрон
П π pi пи
P ρ rho ро
Σ σ sigma сигма
T
τ
tau тау
υ upsilon ипсилон
Ф φ phi фи
Х χ chi хи
Ψ ψ psi пси
Ω ω omega омега

В ожидании «Лямбды»: главный эпидемиолог Тверской области рассказал о нюансах ревакцинации от COVID-19

Наш регион получил первую партию препарата «Спутник Лайт».

Вакцинация против коронавируса в Тверской области идёт с конца 2020 года. Первоначально прививку получало население из групп риска, контактировавшее с большим количеством других людей, — медработники, учителя и так далее. В январе стартовала масштабная прививочная кампания против коронавируса. Она продолжается и по сей день.

Пока одни записываются на первую прививку от COVID-19, другие уже проходят ревакцинацию. Для чего же нужна эта процедура, когда необходимо прививаться повторно и какой вакциной – с этими вопросами корреспондент Tverigrad.ru обратился к главному внештатному эпидемиологу Тверской области Александру Раздорскому.

Как пояснил эксперт, эффективность первой прививки со временем снижается. Кроме того, коронавирус мутирует и каждые новые штаммы становятся более заразными и устойчивыми к антителам. Дополнительная прививка необходима для того, чтобы усилить иммунный ответ на COVID-19.

— Ревакцинация — это явление не новое. Она используется и при вакцинации от других инфекционных болезней. Например, от гепатита B. Первая прививка от гепатита B делается ещё в роддоме, затем от этой болезни вакцинируют ещё два раза с определённым интервалом времени. Такой подход направлен на усиление иммунитета, который формируется в ходе первичной вакцинации. При ревакцинации от COVID-19 цель преследуется точно такая же, — объяснил главный эпидемиолог региона.

Основная задача, которую нужно выполнить в короткие сроки, это формирование коллективного иммунитета к коронавирусу в России. Поэтому Александр Раздорский настоятельно рекомендует через полгода сделать повторную прививку как переболевшим COVID-19, не зависимо от тяжести болезни, так и ранее привитым. В период более спокойной эпидемиологической ситуации эту процедуру можно будет проходить и реже, но до этого надо ещё дойти.

— В данной ситуации вакцинация рассматривается не как профилактическая, а как противоэпидемическая мера. Мы должны побороть эпидемию. Как только в России будет достигнут минимальный порог привитых в 60%, мы сможем перейти к так называемой рутинной вакцинации.

То есть, заниматься вакцинацией тех, кто переболел COVID-19 и ревакцинацией тех, кто сделал прививку, с кратностью примерно раз в полгода, — сказал Александр Раздорский.

Прививаться повторно можно любой зарегистрированной в России вакциной. Но Минздрав РФ рекомендует делать ревакцинацию препаратом «Спутник Лайт». Недавно он поступил в наш регион – 5128 доз. Применение этой прививки предполагает только один укол, в отличие от «Спутника V».

Александр Раздорский отметил, что решение о ревакцинации каждый принимает самостоятельно. Это абсолютно добровольная процедура.

— Я сам спустя полгода сделал ревакцинацию. Я понимаю значимость этого процесса, знаю, что вакцина работает, она меня защищает в условиях достаточно высокого риска инфицирования,

— добавил главный эпидемиолог Тверской области.

Российская вакцина против коронавируса «Спутник V» уже доказала свою эффективность, надёжность и безопасность. На сегодняшний день в Тверской области от COVID привились около 295 тысяч человек.

Заразились после прививки лишь 2470 человек. 

— Это менее 1%. К тому же, они перенесли заражение COVID-19 в лёгкой форме, не нуждались в реанимации. То есть, вакцина более чем в 99% случаях обеспечивает защиту от заболевания. Тяжело заболевают те, кто не завершил полный курс вакцинации, кто заболел после первой прививки. У этих людей не успел сформироваться иммунитет, — пояснил эксперт.

В соцсетях сегодня активно обсуждают очереди перед пунктами вакцинации. Некоторым приходится часами ждать укола от COVID-19, другие, не дождавшись своей очереди, просто уходят в надежде привиться в другой день.

Александр Раздорский объяснил, с чем связан ажиотаж в прививочных зонах: «Очереди вызваны необходимостью вакцинироваться большому количеству людей в сжатые сроки. Это происходит из-за вступившего в силу постановления об обязательной вакцинации отдельных категорий граждан».

Напомним, 18 июня главный санитарный врач Тверской области Арнольд Выскубов подписал постановление, в котором чётко указаны категории граждан, подлежащие обязательной вакцинации. Это работники торговли, сферы услуг, образования, здравоохранения, общепита, транспорта и не только. Сделать укол должны чиновники и муниципальные служащие. Вакцинация первым компонентом или однокомпонентной вакциной не менее 60% от общей численности сотрудников должна быть организована до 18 июля, до 18 августа – вторым компонентом. Постановления не распространяется на лиц, имеющих противопоказания к профилактической прививке против новой коронавирусной инфекции.

— По темпам вакцинации с 18 июня по 18 июля Тверская область вышла на лидирующие позиции по стране. На сегодняшний день мы находимся на четвёртом месте из 85-ти субъектов РФ. Темп вакцинации в Тверской области в полтора раза превышает среднероссийский показатель. Это говорит о том, что работа нашими врачами в прививочных кабинетах, а также на выездной вакцинации проделана колоссальная. Мы за этот месяц привили более 120 тысяч человек. Это огромная цифра. До 1 сентября нам предстоит привить ещё большее количество – не менее 150 тысяч человек.

Сейчас для этого делается всё возможное, — сказал Александр Раздорский.

Кроме того, по словам эксперта, очереди сейчас увеличиваются за счёт тех, кто проходит повторную вакцинацию.

— Мы это прекрасно понимаем. Чтобы избежать столпотворения, мы организуем работу прививочных кабинетов таким образом, чтобы распараллелить поток тех, кто идёт на первый этап вакцинации и тех, кто идёт на второй этап. В торговых центрах работа организована в несколько смен: параллельно работает несколько прививочных бригад в одном пункте. Если мы видим, что где-то скапливается народ, рекомендуем переместиться в близлежащий прививочный кабинет. Например, рядом с «Рубином» находится поликлиника №8. Можно пройти туда, там нет очередей. Однако зачастую граждане обращаются туда, где проще, — говорит эксперт.

Александр Раздорский подчеркнул, что, несмотря на повышение спроса, перебои с поставками препаратов не возникнут. В Тверской области обеспечен достаточный запас.

— На вчерашний день, например, остаток вакцины составляет более 35 тысяч доз. В ближайшие день-два мы ждём поступления ещё более 26 тысяч доз, — сказал главный эпидемиолог региона.

— Александр Сергеевич, как Вы думаете, удастся ли к 1 сентября привить 60% населения Тверской области?


— Я могу лишь сказать, что у нас большие шансы достичь этой цифры. Всё в наличии для этого имеется, — ответил Александр Раздорский.

По его словам, в Тверской области сейчас циркулирует индийский штамм «Дельта», который характеризуется высокой заразностью и тяжелым течением болезни во всех возрастах. А осенью мы можем столкнуться с новым штаммом коронавируса – «Лямбда». Никто не знает, чего от него ждать. Поэтому наш иммунитет должен быть готов к этому противостоянию.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Краткая история Лямбды, или почему Итан привирает / Хабр

В очередном

опусе

Итана Сигеля резанула фраза


Пронаблюдав за удалёнными сверхновыми и измерив, как Вселенная расширялась миллиарды лет, астрономы обнаружили нечто удивительное, загадочное и неожиданное.

И нет, с переводом всё в порядке, в оригинале ещё желтее:


By observing distant supernovae and measuring how the Universe had expanded over billions of years, astronomers discovered something remarkable, puzzling and entirely unexpected

wat?

О какой неожиданности может идти речь? Там ведь совершенно шикарная история длиной в 80 лет с яркими открытиями и закрытиями. История про то, как на самом деле делается настоящая наука. История скорее про физиков, чем про физику.

О чём вообще весь сыр-бор?

Первую версию Общей Теории Относительности (ОТО) Альберт Эйнштейн представил публике 25 ноября 1915 года. В оригинале уравнения ОТО Эйнштейна выглядели вот так:

или, в современной записи, вот так:

Для неумеющего в тензоры читателя понятнее уравнение (1) в оригинальной записи Эйнштейна. Там написано, что энергия-импульс материи G равен кривизне пространства R плюс тензор Риччи S. (Этот самый тензор Риччи тоже есть кривизна, только в более другой форме).
Сейчас, решая уравнение ОТО, энергию-импульс обычно считают известным, а ищут как раз кривизну. Поэтому в современной записи стороны уравнения поменяли местами. Заодно поменяли буковки: G → T, S → Rμν.

Откуда есть пошла лямбда

Одним из первых серьёзных математиков, который занялся проверкой выкладок Эйнштейна, стал Эли Жозеф Картан (не путать с его сыном Анри, тоже известным математиком).

Картан-папа нашёл у Эйнштейна ряд технических ошибок, в частности, такую, которая современному поколению ЕГЭ известна под кодовым названием «потерять константу при интегрировании». Сегодня эту потерянную константу обозначают заглавной греческой буквой лямбда, Λ.

Но физика — это вам не математика. Здесь нельзя взять формулу и напихать в неё добавочных слагаемых просто так. Нужно иметь очень веские основания, и теоретические, и экспериментальные.

Хотя ниже вы увидите, насколько мало Эйнштейн знал о Вселенной в те годы, но тогда, в 1916, такие основания у него были. Альберт Германович точно знал, что звёзды не попадали друг на друга и совершенно не собираются этого делать в обозримом будущем. Однако, в ОТО-1915 было только притяжение, которое нужно было чем-то сбалансировать.

Вводимая в уравнения лямбда как раз отвечала за отталкивание. Поэтому в 1917 Эйнштейн опубликовал «дополненную и улучшенную» версию ОТО с космологической постоянной Λ. В современной записи уравнение выглядит так:

Первое физическое толкование смысла лямбды

Возьмём уравнение ОТО-1917 и вынесем за скобки метрический тензор

. Тогда внутри скобок у нас останется выражение (R/2 — Λ). Здесь R без индексов — это обычная, «школьная» скалярная кривизна. Если на пальцах — это число, обратное радиусу окружности/сферы. Плоскому пространству соответствует R = 0.

В такой трактовке ненулевое значение Λ означает, что наша Вселенная искривлена сама по себе, в том числе и при отсутствии какой-либо гравитации. Ну, вот такой нам достался мир. Однако, большинство физиков в это не верят, и считают, что у наблюдаемого искривления должна быть какая-то внутренняя причина. Какая-то неведомая доселе фигня, которую можно открыть.

Что там не так с измерениями кривизны

На сегодняшний день измеренная кривизна пространства Вселенной таки равна нулю, но с очень паршивой точностью, порядка 0.4%. И не очень-то видно способов эту точность улучшить.

С измерениями кривизны есть две концептуальные проблемы.

Первая в том, что мы не можем измерить совсем пустое пространство, потому что просто ничего там не видим. А если там есть что-то, что мы таки видим, то пространство уже не пустое и, значит, уже дополнительно искривлено гравитацией.

Вторая проблема сложнее и носит персональное название «проблема систем отсчёта». Смысл там вот в чём.

Допустим, у нас есть как-то измеренные координаты объектов, плюс пачка фотографий этих объектов в разных ракурсах (снятых из разных точек). Тогда мы можем вычислить кривизну пространства. Например, гравитация Солнца отклоняет пролетающий мимо свет далёких звёзд. Во время солнечных затмений это отклонение можно измерить экспериментально и сравнить с предсказаниями ОТО.

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

Но вот для далёких галактик всё плохо. Мы не знаем их точных координат. И кривизну пространства на больших масштабах мы тоже не знаем. И даже пачки фотографий у нас нет: на таких масштабах можно считать, что все они сделаны практически из одной точки. Поэтому за пределами Млечного Пути мы не можем быть уверены ни в координатах, ни в кривизне.
И в силу универсальности гравитации это касается не только собственно «фотографий», но абсолютно любых измерений удалённых объектов.

Поэтому измерить кривизну наблюдаемой Вселенной в целом мы можем только из очень окольных соображений.


Вселенная Фридмана

Meanwhile in Russia, не смотря на войны и революции, над теорией ОТО бился прапорщик (и по совместительству профессор) Александр Александрович Фридман. Он рассмотрел все варианты лямбд и выяснил следующее:

При Λ < 0 имеют место лишь силы притяжения, как гравитационные, так и вызванные кривизной впуклоговогнутого пространства. Рано или поздно звёзды и галактики в таком мире таки попадают друг на друга. Причём конец будет неожиданно быстрым и очень горячим.

При Λ > 0 на больших расстояниях заруливает геометрия, а звёзды и галактики ускоренно разлетаются «с горки» (вариант Эйнштейна-1917). При достаточно большой лямбде на небе может вообще ни остаться ни одной звезды кроме Солнца, при умеренном значении — останется только наша галактика, слившаяся с ближайшими соседями.

Но самое интересное происходит при Λ = 0. Здесь всё зависит от начальных условий — т.е. координат и скоростей конкретных галактик. Возможны три варианта: большое сжатие, большой разлёт и стационарный вариант, когда галактики разлетаются, но с относительно небольшими скоростями и без ускорения.

Сегодня вышеописанные ситуации называются космологическими решениями Фридмана.

Статьи Фридмана 1922 и 1924 годов отменяли необходимость в лямбда-члене, из-за чего поначалу были приняты Эйнштейном в штыки.

За свою работу Фридман вполне мог претендовать на Нобелевку.

Но

Летом 1925 он женился, поехал в свадебное путешествие в Крым, съел там немытую грушу, заразился тифом и в сентябре — умер.

Из решений Фридмана вытекало, что у Вселенной может быть начало. Эту идею подхватили многие физики, а возглавил то, что позже назвали «теорией Большого Взрыва», русско-американец Георгий Гамов, полагавший Λ = 0.

И да, статья Итана про примерно такой график (конкретно на этом учтены данные на 2010 год):


Здесь по горизонтали отложено z — это красное смещение, по вертикали наблюдаемая яркость сверхновых особого типа Ia, которые всегда выделяют одно и то же количество энергии. Вообще, это два способа измерения одного и того же расстояния, но, так сказать, в разные моменты времени.

Серые палки — наблюдавшиеся события с их погрешностью измерений. Синим пунктиром отложено предсказание при Λ = 0, красной линией — аппроксимация фактически наблюдаемых значений. Отклонение красной линии от прямой означает, что Вселенная расширяется ускоренно. Но Эйнштейн об этом так и не узнал.

Вселенная Каптейна

Перейдём к экспериментальной части.

Голландский астроном Якобус Корнелиус Каптейн открыл звезду Каптейна в 1897, после чего приступил к opus magnum всей своей жизни. Объединяя огромное количество наблюдений разных обсерваторий, он попытался создать первую карту Вселенной. По его карте выходило, что вселенная имеет форму вращающегося (sic!) диска крышесносящего по тем временам размера 40000 световых лет, причём Солнце находится отнюдь не в центре, а вполне себе на задворках. Закончена и опубликована эта работа была только в 1922.

Для понимания уровня тогдашних знаний: то, что Каптейн считал невероятно огромной Вселенной, сегодня считается совершенно рядовой, ничем не примечательной среди миллиардов таких же… галактикой Млечный Путь. Тем не менее, заслуга Каптейна в том, что он открыл её вращение и приблизительно вычислил её центр.

Наблюдения Хаббла (астронома, а не телескопа)

Если говорить про астрономов, то больше всех для истории лямбды сделал Эдвин Хаббл. Он чувствовал, что с туманностями что-то не так, и в 1922 предположил, что часть из них — не облака газа, а очень удалённые объекты. Проверяя свою теорию, в 1924 он первым в мире разглядел отдельные звёзды в туманности Андромеды (да, ему всю жизнь везло на очень хорошие телескопы. И после смерти — продолжило везти). Именно Хаббл предложил термин «галактика» — собственно, это «млечный путь» по-гречески.

Статью со своими открытиями, из которой следовало, что Вселенная значительно больше, чем наш Млечный путь, Хаббл представил американскому астрономическому обществу первого января 1925. За что и был освистан страдающими от похмелья коллегами, едва свыкшимися с расстояниями Каптейна.

Хаббл не унимался и прикрутил к телескопу ещё и спектрометр. Анализируя красное смещение галактик, он выяснил, что галактики разбегаются, а Вселенная, соответственно, расширяется. Заодно он открыл закон имени себя с константой имени себя (впрочем, закон был предсказан Леметром), и описал всё это в статьях к концу 20-ых годов. Согласно его наблюдениям, оказалась верна модель Фридмана для Λ = 0.

Это выбило из-под лямбды теперь уже и экспериментальные основания её существования.

Эйнштейн, гляда на это, оперативно вычеркнул космологическую постоянную из уравнений ОТО, а в конце жизни считал историю с лямбдой «самой большой своей ошибкой».

Так что, кроме всех своих открытий, Хаббл также невольно «закрыл» лямбду. На целых 70 лет.

Здесь ещё нужно упомянуть, что первоначальные оценки Хаббла были очень уж неточными и показывали возраст Вселенной порядка 2 миллиардов лет. Позднее это войдёт в противоречие с данными геофизиков, которые при помощи радиоизотопного анализа оценят возраст Земли в несколько миллиардов лет, и десятилетиями будет сильнейшей головной болью для физиков-космологов.

Стационарная Вселенная Хойла

С начала 30-ых годов вопрос с лямбдой считался решённым, и из мейнстримных физиков ей никто толком не занимался. Одним из редких исключений, рискнувших попереть супротив самого Эйнштейна, стал британец Фред Хойл.

Оффтоп про Хойла, углерод и три альфы

Речь пойдёт о гелии. Этот элемент феноменально инертен и не хочет ни с чем реагировать. Причём не только химически, но и физически тоже, если мы говорим про гелий-4. Его ядро — альфа частица — имеет пиковую энергию связи на нуклон в своей области. см. рис из какого-то реферата:

Это значит, что альфа-частица не может присоединить дополнительные протоны или другую альфа-частицу иначе как случайно: это просто-напросто энергетически невыгодно. А в ядрах звёзд ничего кроме протонов и альфа-частиц и нет.

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

Ближайшее ядро, в которое может превращаться гелий-4, это углерод-12. Но для этого нужно объединить три альфа-частицы.

Проблема в том, что вероятность столкновения трёх альфа-частиц одновременно слишком мала. А двухшаговый процесс (сначала сталкиваются две частицы, потом очень быстро, пока они не разлетелись обратно на две альфа-частицы, в них врезается ещё одна), в принципе, возможен, но расчёты Эдвина Солпитера показывали, что такой процесс идёт слишком вяло, чтобы производить существенные количества углерода.

И вот весной 1953 года в Калтех приехал британец Фред Хойл, тогда ещё без приставки «сэр», и сразу отправился к местному завлабу Уильяму Фаулеру.

Там он с порога спросил: может ли углерод-12 обладать энергетическим уровнем, равным 7,69 МэВ? Фаулер сначала подумал, что к нему припёрся очередной сумасшедший, но решил спросить — «вообще-то нет, а вам, собственно, зачем?» На что Хойл ответил: ну, я же существую, значит, у ядра углерода должен быть такой энергетический уровень. Отличная аргументация!

Однако, по расчётам Хойла выходило, что при наличии такого уровня в три-альфа процессе наступает резонанс, и звёзды — красные гиганты производят достаточно много углерода для нашего существования.

Удивительно, но американцы решили провести небольшой эксперимент на своём ускорителе. И да — триумфально нашли нужный энергетический уровень на 7.65 МэВ, который физики-ядерщики всего мира почему-то проглядели во всех предыдущих экспериментах.

Сегодня такое возбуждённое состояние углерода-12, когда три альфа-частицы фактически выстраиваются по линии, называется хойловским. Соответствующая статья Хойла, Фаулера и супругов-астрономов Джефри и Маргерит Бёрбиджей является краеугольным камнем современных теорий звёздного нуклеосинтеза и настолько часто цитируется, что обозначается просто B²FH, без ссылок и расшифровок.

И — да, на сегодня это чуть ли не единственное известное успешное предсказание на основе антропного принципа.

Хойл был вполне авторитетным учёным в области космологии, причём, в отличие от многих коллег, так сказать «прикладной», т.е. относительно просто проверяемой, космологии. Именно он объяснил, как из однородных разреженных облаков газа путём гравитационного сжатия образуются звёзды и галактики. Также именно Хойл придумал название «Большой взрыв», причём использовал это название в ругательном смысле.

Хойлу и его соавторам — Бонди и Голду — очень не нравился «большой хлопок» (более корректный перевод фразы big bang), при котором у Вселенной есть начало. Они считали, что так же, как равноправны все точки пространства, должны быть равноправны и все точки во времени. У такой Вселенной нет ни начала, ни конца, и при этом она постоянно, хотя и очень медленно расширяется.

Однако, из квантовых флуктуаций постоянно рождается новое вещество, причём так, что средняя плотность материи остаётся одинаковой. Расчёты показывают, что в одном кубическом километре пространства должен рождаться всего-навсего один протон раз в 300000 лет (а так же один электрон или что-то типа того для сохранения электрического заряда). Прекрасное число, чтобы исключить любую возможность какой-либо экспериментальной проверки!

Теория стационарной Вселенной серьёзно рассматривалась как альтернатива теории Большого Взрыва в 50-х и начале 60-х. Но экспериментальное открытие в 1964 году предсказанного ТББ реликтового излучения поставило на ней крест.

Хойл, впрочем, не унимался и совершенствовал свою теорию до самого выхода на пенсию. Последняя редакция, разработанная на пару с его другом Джефри Бёрбиджем в 1993, так называемая «квази-стационарная Вселенная», предполагает локальные мини-взрывы и объясняет примерно все наблюдаемые факты, но какой-либо популярностью не пользуется. И да, она подозрительно похожа на общепринятую на сегодня теорию инфляции (но отличается знаками плюс-минус в некоторых местах).

За статью B²FH дали Нобелевку. Но только Фаулеру, который распорядился провести десятидневный эксперимент. Ни супругам Бёрбиджам, проводившим длительные астрономические наблюдения и собственно написавшим статью, ни автору идеи Хойлу нобелевку не дали — за упорствование в космологической ереси.

Самое интересное, что Хойл дожил до экспериментального подтверждения ускоренного разбегания галактик в 1998. Но даже это не стало поводом для нобелевского комитета исправить очевидную ошибку.

Квантовая лямбда

Вернёмся к уравнению ОТО.

Слева (в современной записи) стоит кривизна пространства, сиречь гравитация по ОТО. Справа — тензор энергии-импульса. Под этим тензором стоит жутко сложный матан, но суть в следующем: там учтена вся-вся-вся материя Вселенной во всех видах и состояниях. И обычное вещество, и всякие хитрые частицы, и все виды излучений (кроме гравитации, которая слева).

Теперь мысленно перенесём лямбду вправо. В такой записи это будет не дополнительная кривизна, а какая-то неучтённая энергия (замечу, отрицательная, раз уж мы считаем лямбду положительной). И здесь просматриваются две возможности.

Первая гипотеза состоит в том, что лямбда — это энергия собственно вакуума. Звучит диковато, но на самом деле вполне согласуется с квантовой механикой. Возьмём кусок пространства и уберём из него всё, что хотя бы в принципе можно убрать. Уберём всё вещество, все частицы и все волны, независимо от их природы. Останутся только физические поля в невозмущённом состоянии. Полный штиль.

Так вот, у некоторых полей (например, Хиггсовских) в пустоте ненулевое значение. И теоретически у них есть некоторая энергия. Кроме того, в силу принципа неопределённости у любых полей есть квантовые флуктуации — и они тоже имеют некоторую энергию.

Возникает, правда, маленькая техническая проблемка. Если всё аккуратно посчитать, расчётный результат отличается от наблюдаемого на 120 — нет, не раз, на 120 порядков. В 100 миллиардов миллиардов гуглов раз! Это по праву считается «худшим предсказанием в истории теоретической физики».

Вторая возможность: физики всё-таки забыли что-то посчитать, когда вычисляли тензор энергии-импульса. Это «что-то» должно быть весьма странным (давать отрицательное давление), ничего похожего мы пока не знаем, так что тут скорее ситуация «не знал — не знал, и забыл». Сейчас это «что-то» называется «тёмная энергия», и этой энергии должно быть примерно в два раза больше, чем энергии у обычной и тёмной материи вместе взятых. ← современная физика находится здесь.

Вместо заключения

Звоночки о ненулевом значении лямбды начали появляться на рубеже 90-ых — из точных измерений реликтового излучения и т.д., и к 1997 превратились в набат. Совсем неудивительно, что сразу две группы физиков вооружились современными инструментами и бросились перепроверять дедушку Хаббла. Поэтому, когда Итан пишет про «совершенно неожиданно», он, мягко говоря, привирает.

И пока для объяснения лямбды у нас нет ничего лучше «тёмной энергии», эта история будет продолжаться.

Спасибо за внимание!

Функция ЛЯМБДА (LAMBDA) — Справочник

Функция ЛЯМБДА (LAMBDA) используется для создания пользовательских, повторно используемых функций и вызова их по выбранному имени. Новая функция доступна во всей книге Excel.

Описание функции Функция ЛЯМБДА на момент добавления в справочник (4 фувраля 2021 года) находилась в «быстром кругу» тестирования программы Office Insider, это значит, что функция не только не доступна обычным пользователям Microsoft 365 (ранее Office 365), но и не все тестировщики имеют возможность ею воспользоваться.

Более того, Microsoft еще даже не определилась в какой категории будет находиться данная функция и, при попытке осуществить поиск в самом приложении Excel — выдает категорию «Рекомендованные», которая по сути является опциональной, если не было найдено точного соответствия. Естественно, вставить функции не вводом с клавиатуры, а через вкладку «Формулы» — не получается, она попросту отсутствует во всех категориях.

Поэтому данная функция помещена в категорию «Экспериментальные».

В простой формулировке функция ЛЯМБДА, позволяет создать пользователю свою функцию без применения макросов и навыков работы VBA.

Синтаксис
=ЛЯМБДА([параметр1;параметр2;...;] вычисление)

Аргументы

параметрвычисление

Необязательный аргумент. Значение, которое вы хотите передать функции, например ссылку на ячейку, строку или число. Можно ввести до 253 параметров

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

Замечания
  • Если ввести более 253 параметров, Excel вернет ошибку «#ЗНАЧ!»
  • Функция ЛЯМБДА анонсирована после выхода Office 2019, поэтому нужно использовать Office по подписке, либо дождаться следующего большого обновления Office
  • Если в функцию ЛЯМБДА передано неправильное число аргументов, Excel возвращает ошибку «#ЗНАЧ!»
  • Если создать функцию ЛЯМБДА в ячейке, не вызывая ее из ячейки, Excel вернет ошибку «#ВЫЧИСЛ!»
  • Имена и параметры «Лямбда» должны следовать синтаксисам имен Excel за одним исключением: не используйте точка (.) в имени параметра

Создание функции ЛЯМБДА
Шаг1. Проверка формулы

Убедитесь, что формула, используемая в аргументе вычисления, работает правильно. Это крайне важно, поскольку при создании функции ЛЯМБДА необходимо убедиться в том, что формула работает, и исключить ее в случае ошибок или неожиданных ситуаций.

Шаг2. Создание Лямбда в ячейке

Лучше всего создать и проверить функцию ЛЯМБДА в ячейке, чтобы убедиться в ее правильности, включая определение и передачу параметров. Чтобы избежать #CALC! добавьте звонок к функции ЛЯМБДА, чтобы немедленно вернуть результат:

=ЛЯМБДА ([параметр1; параметр2; …];вычисление) (вызов функции)

В следующем примере возвращается значение 2.

=LAMBDA(number, number + 1)(1)
Шаг3. Добавление Лямбда в диспетчер имен

Завершив работу с функцией ЛЯМБДА, переместит ее в диспетчер имен для окончательного определения. Таким образом вы даете функции ЛЯМБДА понятное имя, даете описание и позволяет повторно работать с любой ячейкой в книге. Можно также управлять функцией ЛЯМБДА для любого имени, например для строковой константы, диапазона ячеек или таблицы.

Пример

Видео работы функции

Как использовать в Python лямбда-функции

В Python и других языках, таких как Java, C# и даже C++, в их синтаксис добавлены лямбда-функции, в то время как языки, такие как LISP или семейство языков ML, Haskell, OCaml и F#, используют лямбда-выражения.

Python-лямбды — это маленькие анонимные функции, подчиняющиеся более строгому, но более лаконичному синтаксису, чем обычные функции Python.

К концу этой статьи вы узнаете:

  • Как появились лямбды в Python
  • Как лямбды сравниваются с обычными объектами функций
  • Как написать лямбда-функцию
  • Какие функции в стандартной библиотеке Python используют лямбда-выражения
  • Когда использовать или избегать лямбда-функций

Примечания: Вы увидите несколько примеров кода с использованием лямбды, которые явно игнорируют лучшие практики стиля Python. Это предназначено только для иллюстрации концепций лямбда-исчисления или для демонстрации возможностей лямбд.

Эти сомнительные примеры будут противопоставляться лучшим подходам или альтернативам по мере прохождения статьи.

Все примеры, включенные в это руководство, были протестированы в Python 3.7.

Лямбда-исчисление

Лямбда-выражения в Python и других языках программирования имеют свои корни в лямбда-исчислении, модели вычислений, изобретенной Алонзо Черчем (Alonzo Church). Далее мы расскажем, когда появилось лямбда-исчисление и почему эта фундаментальная концепция появилась в экосистеме Python.

История

Алонзо Черч формализовал лямбда-исчисление, как язык, основанный на чистой абстракции, в 1930-х годах. Лямбда-функции также называют лямбда-абстракциями, прямой ссылкой на абстракционную модель первоначального творения Алонзо Черч.

В лямбда-исчисление можно закодировать любое вычисление. Оно является полным по Тьюрингу, но вопреки концепции машины Тьюринга оно является чистым и не сохраняет никакого состояния.

Функциональные языки берут свое начало в математической логике и лямбда-исчислении, в то время как императивные языки программирования охватывают основанную на состоянии модель вычислений, изобретенную Аланом Тьюрингом. Две модели вычислений, лямбда-исчисление и машины Тьюринга, могут быть переведены друг в друга. Эта эквивалентность известна как гипотеза Чёрча-Тьюринга.

Функциональные языки напрямую наследуют философию лямбда-исчисления, применяя декларативный подход программирования, которое придает особое значение абстракции, преобразование данных, композицию и чистоту (без состояния и без побочных эффектов). Примерами функциональных языков являются Haskell, Lisp или Erlang.

Напротив, машина Тьюринга привела к императивному программированию, используемому в таких языках, как Fortran, C или Python.

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

Разделение в обоих подходах относительное, поскольку некоторые функциональные языки включают императивные функции, такие как OCaml, в то время как функциональные функции проникают в императивное семейство языков, в частности, с введением лямбда-функций в Java или Python.

Python по своей сути не является функциональным языком, но на раннем этапе он принял некоторые функциональные концепции. В январе 1994 года к языку были добавлены map(), filter(), reduce() и лямбда-оператор.

Первый пример

Вот несколько примеров, чтобы продемонстрировать функциональный стиль.

Функция тождества (identity function), функция, которая возвращает свой аргумент, выражается стандартным определением функции Python с использованием ключевого слова def следующим образом:

>>> def identity(x):
...   return x

identity() принимает аргумент x и возвращает его при вызове.

Если вы воспользуетесь лямбда-конструкцией, ваш код будет следующим:

>>> lambda x: x

В приведенном выше примере выражение состоит из:

  • Ключевое слово: lambda
  • Связанная переменная: x
  • Тело: х

Примечание. В контексте этой статьи связанная переменная является аргументом лямбда-функции.

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

Напишем немного более сложный пример, функцию, которая добавляет 1 к аргументу, следующим образом:

>>> lambda x: x + 1

Применим указанную выше функцию к аргументу, заключив функцию и ее аргумент в круглые скобки:

>>> (lambda x: x + 1)(2)
3

Сокращение — это стратегия лямбда-исчисления для вычисления значения выражения. Оно состоит из замены аргумента x на 2:

(lambda x: x + 1)(2) = lambda 2: 2 + 1
                     = 2 + 1
                     = 3

Поскольку лямбда-функция является выражением, оно может быть именована. Поэтому вы можете написать предыдущий код следующим образом:

>>> add_one = lambda x: x + 1
>>> add_one(2)
3

Вышеупомянутая лямбда-функция эквивалентна написанию этого:

def add_one(x):
    return x + 1

Все эти функции принимают один аргумент. Возможно, вы заметили, что в определении лямбды аргументы не имеют круглых скобок вокруг них. Функции с несколькими аргументами (функции, которые принимают более одного аргумента) выражаются в лямбда-выражениях Python, перечисляя аргументы и разделяя их запятой (,), но не заключая их в круглые скобки:

>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'

Лямбда-функция full_name, принимает два аргумента и возвращает строку, интерполирующую два параметра: первый и последний. Как и ожидалось, определение лямбды перечисляет аргументы без скобок, тогда как вызов функции выполняется точно так же, как и обычная функция Python, с круглыми скобками вокруг аргументов.

Анонимные функции

Следующие термины могут использоваться взаимозаменяемо в зависимости от языка программирования:

  • Анонимные функции
  • Лямбда-функции
  • Лямбда-выражения
  • Лямбда-абстракции
  • Лямбда-форма
  • Функциональные литералы

В оставшейся части этой статьи после этого раздела вы в основном увидите термин лямбда-функция.

В буквальном смысле, анонимная функция — это функция без имени. В Python анонимная функция создается с помощью ключевого слова lambda. Рассмотрим анонимную функцию с двумя аргументами, определенную с помощью лямбды, но не связанную с переменной.

>>> lambda x, y: x + y

Вышеприведенная функция определяет лямбда-выражение, которое принимает два аргумента и возвращает их сумму.

Помимо демонстрации того, что Python отлично подходит для этой идеи, это никак нельзя практически использовать. Вы можете вызвать эту функцию в интерпретаторе Python:

>>> _(1, 2)
3

В приведенном выше примере используется только функция интерактивного транслятора, представленная через символ подчеркивания (_).

Вы не можете написать подобный код в модуле Python. Рассматривайте _ в интерпретаторе как побочный эффект, которым мы воспользовались. В модуле Python вы бы присваивали лямбда-имя или передавали лямбда-функцию. Мы будет использовать эти два подхода позже в этой статье.

Примечание. В интерактивном интерпретаторе подчеркивание (_) привязано к последнему вычисленному выражению.

Для получения более подробной информации об использовании этого специального символа в Python, посмотрите Значение подчеркивания в Python (The Meaning of Underscores in Python).

Другой шаблон, используемый в других языках, таких как JavaScript, — это немедленное выполнение лямбда-функции Python. Это называется выражением немедленного вызова функции (IIFE —  Immediately Invoked Function Expression, произносится «iffy»). Вот пример:

>>> (lambda x, y: x + y)(2, 3)
5

Вышеприведенная лямбда-функция определяется, а затем сразу вызывается с двумя аргументами (2 и 3). Возвращает значение 5, которое является суммой аргументов.

Несколько примеров в этом руководстве используют этот формат, чтобы выделить анонимный аспект лямбда-функции и избежать сосредоточения внимания на лямбда-выражениях в Python как более коротком способе определения функции.

Лямбда-функции часто используются с функциями более высокого порядка, которые принимают одну или несколько функций в качестве аргументов или возвращают одну или несколько функций.

Лямбда-функция может быть функцией более высокого порядка, принимая функцию (нормальную или лямбда-функцию) в качестве аргумента, как в следующем надуманном примере:

>>> high_ord_func = lambda x, func: x + func(x)
>>> high_ord_func(2, lambda x: x * x)
6
>>> high_ord_func(2, lambda x: x + 3)
7

Python содержит функции высшего порядка в виде встроенных функций или в стандартной библиотеке. Примеры функций высшего порядка map(), filter(), functools.reduce(), а также такие ключевые функции, как sort(), sorted(), min() и max(). Мы продемонстрируем использование лямбда-функции вместе с функциями высшего порядка в разделе «Соответствующее использование лямбда-выражений».

Лямбда и обычные функции

Эта цитата из часто задаваемых вопросов по Python Design and History FAQ, похоже, задает тон в отношении общего ожидания использования лямбда-функций в Python:

В отличие от лямбда функций в других языках, где они добавляют функциональность, лямбды в Python являются лишь сокращенной записью, если вы слишком ленивы, чтобы определить функцию. (Source)

Тем не менее, не позволяйте этому утверждению удерживать вас от использования lambda. На первый взгляд, вы можете согласиться с тем, что лямбда-функция — это функция с некоторым синтаксическим сахаром, сокращающим код для определения или вызова функции. В следующих разделах освещены общие черты и тонкие различия между обычными функциями Python и лямбда-функциями.

Функции

В этот момент вы можете задаться вопросом, что принципиально отличает лямбда-функцию, привязанную к переменной, от обычной функции с единственной строкой return: кажется что почти ничего. Давайте проверим, как Python видит функцию, созданную с помощью одного оператора return, по сравнению с функцией, созданной с выражением lambda.

Модуль dis предоставляет функции для анализа байт-кода Python, сгенерированного компилятором Python:

>>> import dis
>>> add = lambda x, y: x + y
>>> type(add)
<class 'function'>
>>> dis.dis(add)
  1           0 LOAD_FAST                0 (x)
              2 LOAD_FAST                1 (y)
              4 BINARY_ADD
              6 RETURN_VALUE
>>> add
<function <lambda> at 0x7f30c6ce9ea0>

Вы можете видеть, что dis() предоставляет читаемую версию байт-кода Python, позволяющую проверять низкоуровневые инструкции, которые интерпретатор Python будет использовать при выполнении программы.

Теперь посмотрим на обычный объект функции:

>>> import dis
>>> def add(x, y): return x + y
>>> type(add)
<class 'function'>
>>> dis.dis(add)
  1           0 LOAD_FAST                0 (x)
              2 LOAD_FAST                1 (y)
              4 BINARY_ADD
              6 RETURN_VALUE
>>> add
<function add at 0x7f30c6ce9f28>

Байт-код, интерпретируемый Python, одинаков для обеих функций. Но вы можете заметить, что наименование отличается: имя добавляется для функции, определенной с помощью def, тогда как лямбда-функция Python рассматривается как лямбда-выражение.

Traceback

В предыдущем разделе вы видели, что в контексте лямбда-функции Python не предоставлял имя функции, а только <lambda> . Это может быть ограничением, которое следует учитывать при возникновении исключения, и в результате трассировки отображается только:

>>> div_zero = lambda x: x / 0
>>> div_zero(2)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 1, in <lambda>
ZeroDivisionError: division by zero

Трассировка исключения, возникшего при выполнении лямбда-функции, идентифицирует только функцию, вызывающую исключение, как <lambda> .

Вот то же исключение, вызванное в нормальной функции:

>>> def div_zero(x): return x / 0
>>> div_zero(2)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 1, in div_zero
ZeroDivisionError: division by zero

Нормальная функция вызывает аналогичную ошибку, но приводит к более точной трассировке, потому что у нее есть имя функции, div_zero.

Синтаксис

Как вы видели в предыдущих разделах, лямбда имеет синтаксические отличия от нормальной функции. В частности, лямбда имеет следующие характеристики:

  • Она может содержать только выражения и не может включать операторы в свое тело.
  • Она пишется как одна строка исполнения.
  • Она не поддерживает аннотации типов.
  • Она может быть немедленно вызвана (IIFE).

Отсутствие утверждений

Лямбда-функция не может содержать утверждения. В лямбда-функции такие операторы, как return, pass, assert или raise, вызовут исключение SyntaxError. Вот пример добавления assert к телу лямбды:

>>> (lambda x: assert x == 2)(2)
  File "<input>", line 1
    (lambda x: assert x == 2)(2)
                    ^
SyntaxError: invalid syntax

Этот надуманный пример демонстрирующий что с помощью assert, утверждается что параметр x имеет значение 2. Но интерпретатор выдает SyntaxError при синтаксическом анализе кода, который включает в себя утверждение assert в теле лямбда-выражения.

Одиночное выражение

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

>>> (lambda x:
... (x % 2 and 'odd' or 'even'))(3)
'odd'

Приведенный выше пример возвращает строку «odd», если лямбда-аргумент нечетный, и «even», когда аргумент четный. Он распространяется на две строки, поскольку содержится в скобках, но остается одним выражением.

Аннотации типов

Если вы начали применять анотации типов, которые теперь доступны в Python, у вас есть еще одна веская причина предпочесть нормальные функции лямбда-функциям Python. В лямбда-функции нет эквивалента для следующего:

def full_name(first: str, last: str) -> str:
    return f'{first.title()} {last.title()}'

Любая ошибка типа в full_name() может быть обнаружена такими инструментами, как mypy или pyre, тогда как в эквивалентной лямбда-функцией сразу будет ошибка SyntaxError во время выполнения:

>>> lambda first: str, last: str: first.title() + " " + last.title() -> str
  File "<stdin>", line 1
    lambda first: str, last: str: first.title() + " " + last.title() -> str

SyntaxError: invalid syntax

IIFE

Вы уже видели несколько примеров немедленного запуска функции:

>>> (lambda x: x * x)(3)
9

Вне интерпретатора эта функция, вероятно, не будет используется на практике. Это прямое следствие того, что лямбда-функция вызывается сразу после того, как она определена. Но, это конструкция позволяет передать определение лямбды в функцию более высокого порядка, например map(), filter() или functools.reduce().

Аргументы

Как и обычный объект функции, определенный с помощью def, лямбда поддерживают все различные способы передачи аргументов. Это включает:

  • Позиционные аргументы
  • Именованные аргументы (иногда называемые ключевыми аргументами)
  • Переменный список аргументов (часто называемый varargs)
  • Переменный список аргументов ключевых слов
  • Аргументы только для ключевых слов

Следующие примеры иллюстрируют опции, доступные для передачи аргументов в лямбда-выражения:

>>> (lambda x, y, z: x + y + z)(1, 2, 3)
6
>>> (lambda x, y, z=3: x + y + z)(1, 2)
6
>>> (lambda x, y, z=3: x + y + z)(1, y=2)
6
>>> (lambda *args: sum(args))(1,2,3)
6
>>> (lambda **kwargs: sum(kwargs. values()))(one=1, two=2, three=3)
6
>>> (lambda x, *, y=0, z=0: x + y + z)(1, y=2, z=3)
6

Декораторы

В Python декоратор — это реализация шаблона, который позволяет добавить поведение к функции или классу. Обычно это выражается синтаксисом @decorator с префиксом функции. Вот пример:

def some_decorator(f):
    def wraps(*args):
        print(f"Calling function '{f.__name__}'")
        return f(args)
    return wraps

@some_decorator
def decorated_function(x):
    print(f"With argument '{x}'")

В приведенном выше примере some_decorator() — это функция, которая добавляет поведение к decorated_function(), так что при вызове decorated_function(2) получается следующий результат:

Calling function 'decorated_function'
With argument 'Python'

decorated_function() печатает только With argument ‘Python’, но декоратор добавляет дополнительное поведение, которое также печатает Calling function ‘decorated_function’.

Декоратор может быть применен к лямбде. Хотя невозможно декорировать лямбду с помощью синтаксиса @decorator, декоратор — это просто функция, поэтому он может вызывать функцию лямбда:

 1 # Defining a decorator
 2 def trace(f):
 3     def wrap(*args, **kwargs):
 4         print(f"[TRACE] func: {f.__name__}, args: {args}, kwargs: {kwargs}")
 5         return f(*args, **kwargs)
 6 
 7     return wrap
 8 
 9 # Applying decorator to a function
10 @trace
11 def add_two(x):
12     return x + 2
13 
14 # Calling the decorated function
15 add_two(3)
16 
17 # Applying decorator to a lambda
18 print((trace(lambda x: x ** 2))(3))

add_two(), декорирована @trace в строке 11, вызывается с аргументом 3 в строке 15. В отличие от этого, в строке 18 сразу же включается лямбда-функция и встраивается в вызов метода trace(), декоратора. Когда вы выполняете код выше, вы получаете следующее:

[TRACE] func: add_two, args: (3,), kwargs: {}
[TRACE] func: <lambda>, args: (3,), kwargs: {}
9

Посмотрите, как, как вы уже видели, имя лямбда-функции выглядит как <lambda>, тогда как add_two четко идентифицировано как обычная функция.

Декорирование лямбды таким способом может быть полезно для целей отладки, возможно, для отладки поведения лямбды, используемой в контексте функции более высокого порядка или ключевой функции. Давайте посмотрим пример с map():

list(map(trace(lambda x: x*2), range(3)))

Первый аргумент map() — это лямбда, которая умножает свой аргумент на 2. Эта лямбда декорирована trace(). При выполнении приведенный выше пример выводит следующее:

[TRACE] Calling <lambda> with args (0,) and kwargs {}
[TRACE] Calling <lambda> with args (1,) and kwargs {}
[TRACE] Calling <lambda> with args (2,) and kwargs {}
[0, 2, 4]

Результат [0, 2, 4] представляет собой список, полученный умножением каждого элемента range(3). range(3) является простым списком [0, 1, 2].

Замыкание

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

Понятия лямбды и замыкания не обязательно связаны, хотя лямбда-функции могут быть замыканиями так же, как обычные функции также могут быть замыканиями. Некоторые языки имеют специальные конструкции для замыкания или лямбды (например, Groovy с анонимным блоком кода в качестве объекта Closure) или лямбда-выражения (например, лямбда-выражения Java с ограниченным параметром для замыкания).

Вот пример замыкания, построенное с помощью обычной функции Python:

 1 def outer_func(x):
 2     y = 4
 3     def inner_func(z):
 4         print(f"x = {x}, y = {y}, z = {z}")
 5         return x + y + z
 6     return inner_func
 7 
 8 for i in range(3):
 9     closure = outer_func(i)
10     print(f"closure({i+5}) = {closure(i+5)}")

outer_func() возвращает inner_func(), вложенную функцию, которая вычисляет сумму трех аргументов:

  • x передается в качестве аргумента outer_func().
  • y является локальной переменной для outer_func().
  • z аргумент, передаваемый в inner_func().

Чтобы продемонстрировать поведение outer_func() и inner_func(), outer_func() вызывается три раза в цикле for, который выводит следующее:

x = 0, y = 4, z = 5
closure(5) = 9
x = 1, y = 4, z = 6
closure(6) = 11
x = 2, y = 4, z = 7
closure(7) = 13

В строке 9 кода inner_func(), возвращаемый вызовом outer_func(), привязывается к имени замыкания. В строке 5 inner_func() захватывает x и y, потому что он имеет доступ к своей области видимости, так что при вызове замыкания он может работать с двумя свободными переменными x и y.

Точно так же лямбда также может быть замыканием. Вот тот же пример с лямбда-функцией Python:

def outer_func(x):
    y = 4
    return lambda z: x + y + z

for i in range(3):
    closure = outer_func(i)
    print(f"closure({i+5}) = {closure(i+5)}")

Когда вы выполняете приведенный выше код, вы получаете следующий вывод:

closure(5) = 9
closure(6) = 11
closure(7) = 13

В строке 6 outer_func() возвращает лямбду и присваивает ее переменную замыкания. В строке 3 тело лямбда-функции ссылается на x и y. Переменная y доступна во время определения, тогда как x определяется во время выполнения, когда вызывается outer_func().

В этой ситуации и нормальная функция, и лямбда ведут себя одинаково. В следующем разделе вы увидите ситуацию, когда поведение лямбды может быть обманчивым из-за времени его оценки (время определения против времени выполнения).

Время оценки

В некоторых ситуациях, связанных с циклами, поведение лямбда-функции Python как замыкания может быть нелогичным. Это требует понимания, когда свободные переменные связаны в контексте лямбды. Следующие примеры демонстрируют разницу при использовании обычной функции по сравнению с лямбда-выражением Python.

Сначала протестируем сценарий, используя обычную функцию:

 1 >>> def wrap(n):
 2 ...     def f():
 3 ...         print(n)
 4 ...     return f
 5 ...
 6 >>> numbers = 'one', 'two', 'three'
 7 >>> funcs = []
 8 >>> for n in numbers:
 9 . ..     funcs.append(wrap(n))
10 ...
11 >>> for f in funcs:
12 ...     f()
13 ...
14 one
15 two
16 three

В нормальной функции n вычисляется во время определения, в строке 9, когда функция добавляется в список: funcs.append (wrap (n)).

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

 1 >>> numbers = 'one', 'two', 'three'
 2 >>> funcs = []
 3 >>> for n in numbers:
 4 ...     funcs.append(lambda: print(n))
 5 ...
 6 >>> for f in funcs:
 7 ...     f()
 8 ...
 9 three
10 three
11 three

Неожиданный результат возникает из-за того, что свободная переменная n, как она реализована, связана во время выполнения лямбда-выражения. Лямбда-функция Python в строке 4 является замыканием, которое захватывает n, свободную переменную, ограниченную во время выполнения. Во время выполнения при вызове функции f из строки 7 значение n равно three.

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

 1 >>> numbers = 'one', 'two', 'three'
 2 >>> funcs = []
 3 >>> for n in numbers:
 4 ...     funcs.append(lambda n=n: print(n))
 5 ...
 6 >>> for f in funcs:
 7 ...     f()
 8 ...
 9 one
10 two
11 three

Лямбда ведет себя как нормальная функция в отношении аргументов. Следовательно, лямбда-параметр может быть инициализирован значением по умолчанию: параметр n принимает значение n по умолчанию для внешнего n. Лямбда может бы быть записана как lambda x=n: print(x) и вернуть такой же результат.

Лямбда вызывается без аргумента в строке 7 и использует значение по умолчанию n, установленное во время определения.

Тестирование Лямбды

Лямбды можно тестировать аналогично обычным функциям. Можно использовать как unittest, так и doctest.

unittest

Модуль unittest обрабатывает лямбда-функции Python аналогично обычным функциям:

import unittest

addtwo = lambda x: x + 2

class LambdaTest(unittest.TestCase):
    def test_add_two(self):
        self.assertEqual(addtwo(2), 4)

    def test_add_two_point_two(self):
        self.assertEqual(addtwo(2.2), 4.2)

    def test_add_three(self):
        # Should fail
        self.assertEqual(addtwo(3), 6)

if __name__ == '__main__':
    unittest. main(verbosity=2)

LambdaTest определяет тестовый пример с тремя методами тестирования, каждый из которых использует сценарий тестирования для addtwo(), реализованной как лямбда-функция. Выполнение Python-файла lambda_unittest.py, содержащего LambdaTest, приводит к следующему:

$ python lambda_unittest.py
test_add_three (__main__.LambdaTest) ... FAIL
test_add_two (__main__.LambdaTest) ... ok
test_add_two_point_two (__main__.LambdaTest) ... ok

======================================================================
FAIL: test_add_three (__main__.LambdaTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lambda_unittest.py", line 18, in test_add_three
    self. assertEqual(addtwo(3), 6)
AssertionError: 5 != 6

----------------------------------------------------------------------
Ran 3 tests in 0.001s

FAILED (failures=1)

Как и ожидалось, у нас есть два успешных тестовых примера и один сбой для test_add_three: результат равен 5, но ожидаемый результат равен 6. Этот сбой вызван преднамеренной ошибкой в тестовом примере. Изменение ожидаемого результата с 6 на 5 удовлетворит все тесты для LambdaTest.

doctest

Модуль doctest извлекает интерактивный код Python из docstring для выполнения тестов. Хотя синтаксис лямбда-функций Python не поддерживает типичную docstring, можно присвоить строку элементу __doc__ именованной переменной лямбды:

addtwo = lambda x: x + 2
addtwo. __doc__ = """Add 2 to a number.
    >>> addtwo(2)
    4
    >>> addtwo(2.2)
    4.2
    >>> addtwo(3) # Should fail
    6
    """

if __name__ == '__main__':
    import doctest
    doctest.testmod(verbose=True)

Тест doctest в комментарии к функции lambda addtwo() описывает те же тесты, что и в предыдущем разделе.

Когда вы выполняете тесты с помощью doctest.testmod(), вы получаете следующее:

$ python lambda_doctest.py
Trying:
    addtwo(2)
Expecting:
    4
ok
Trying:
    addtwo(2.2)
Expecting:
    4.2
ok
Trying:
    addtwo(3) # Should fail
Expecting:
    6
**********************************************************************
File "lambda_doctest.py", line 16, in __main__.addtwo
Failed example:
    addtwo(3) # Should fail
Expected:
    6
Got:
    5
1 items had no tests:
    __main__
**********************************************************************
1 items had failures:
   1 of   3 in __main__. addtwo
3 tests in 2 items.
2 passed and 1 failed.
***Test Failed*** 1 failures.

Неудачные результаты теста от того же сбоя, объясненного в выполнении модульных тестов в предыдущем разделе.

Вы можете добавить docstring к лямбда-выражению через присвоение __doc__ для документирования лямбда-функции. Хотя это возможно, синтаксис docstring все же лучше использовать для нормальных функций, а не для лямбда-функции.

Злоупотребления лямбда-выражениями

Несколько примеров в этой статье, если они написаны в контексте профессионального кода Python, будут квалифицированы как злоупотребления.

Если вы обнаружите, что пытаетесь использовать что-то, что не поддерживает лямбда-выражение, это, вероятно, признак того, что нормальная функция подойдет лучше. Хорошим примером является docstring для лямбда-выражения в предыдущем разделе. Попытка преодолеть тот факт, что лямбда-функция Python не поддерживает операторы, является еще одним красным флагом.

Следующие разделы иллюстрируют несколько примеров использования лямбды, которых следует избегать. Такими примерами могут быть ситуации, когда в контексте лямбда-кода Python код демонстрирует следующий шаблон:

  • Он не следует руководству по стилю Python (PEP 8)
  • Код выглядит громоздким и трудно читаемым.

Возникновение исключения

Попытка вызвать исключение в лямбда-выражении Python заставит вас задуматься дважды. Есть несколько способов сделать это, но лучше избегать чего-то вроде следующего:

>>> def throw(ex): raise ex
>>> (lambda: throw(Exception('Something bad happened')))()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 1, in <lambda>
    File "<stdin>", line 1, in throw
Exception: Something bad happened

Поскольку утверждением не является синтаксически правильным в лямбда-теле Python, обходной путь в приведенном выше примере состоит в абстрагировании вызова оператора с помощью специальной функции throw(). Следует избегать использования этого типа обходного пути. Если вы сталкиваетесь с этим типом кода, вам следует рассмотреть возможность рефакторинга кода для использования обычной функции.

Загадочный стиль

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

Следующий лямбда-пример содержит несколько неудачных стилей:

>>> (lambda _: list(map(lambda _: _ // 2, _)))([1,2,3,4,5,6,7,8,9,10])
[0, 1, 1, 2, 2, 3, 3, 4, 4, 5]

Подчеркивание (_) относится к переменной, на которую вам не нужно ссылаться в явном виде. Но в этом примере три _ относятся к разным переменным. Первоначальным рефакторингом этого лямбда-кода может быть присвоение имен переменным:

>>> (lambda some_list: list(map(lambda n: n // 2,
                                some_list)))([1,2,3,4,5,6,7,8,9,10])
[0, 1, 1, 2, 2, 3, 3, 4, 4, 5]

По общему признанию, это все еще трудно будет читать. Все еще используя лямбду, обычная функция может сделать этот код более читабельным, распределив логику по нескольким строкам и вызовам функций:

>>> def div_items(some_list):
      div_by_two = lambda n: n // 2
      return map(div_by_two, some_list)
>>> list(div_items([1,2,3,4,5,6,7,8,9,10])))
[0, 1, 1, 2, 2, 3, 3, 4, 4, 5]

Это все еще не оптимально, но показывает вам возможный путь для создания кода и, в частности, лямбда-функций Python, более удобочитаемых. В разделе Альтернативы лямбда-выражениям вы научитесь заменять map() и лямбда-выражения на списки или выражения-генераторы. Это значительно улучшит читабельность кода.

Классы Python

Вы можете, но не должны писать методы класса как лямбда-функции Python. Следующий пример является совершенно допустимым кодом Python, но демонстрирует нетрадиционный код, основанный на лямбде. Например, вместо реализации __str__ как обычной функции он использует лямбду. Аналогично, brand и year — это свойства, также реализованные с помощью лямбда-функций вместо обычных функций или декораторов:

class Car:
    """Car with methods as lambda functions."""
    def __init__(self, brand, year):
        self.brand = brand
        self. year = year

    brand = property(lambda self: getattr(self, '_brand'),
                     lambda self, value: setattr(self, '_brand', value))

    year = property(lambda self: getattr(self, '_year'),
                    lambda self, value: setattr(self, '_year', value))

    __str__ = lambda self: f'{self.brand} {self.year}'  # 1: error E731

    honk = lambda self: print('Honk!')     # 2: error E731

При запуске такого инструмента, как flake8, инструмент обеспечения соблюдения стилей, будут отображаться следующие ошибки для __str__ и honk:

E731 do not assign a lambda expression, use a def

Хотя flake8 не указывает на проблему использования лямбда-функций в свойствах, их трудно читать и они подвержены ошибкам из-за использования нескольких строк, таких как _brand и _year.

Ожидается, что правильная реализация __str__ будет выглядеть следующим образом:

def __str__(self):
    return f'{self.brand} {self.year}'

brand будет написана следующим образом:

@property
def brand(self):
    return self._brand

@brand.setter
def brand(self, value):
    self._brand = value

Как правило, в контексте кода, написанного на Python, предпочитайте обычные функции лямбда-выражениям. Тем не менее, есть случаи, в которых используется лямбда-синтаксис, как вы увидите в следующем разделе.

Правильное использование лямбда-выражений

Лямбды в Python, как правило, являются предметом споров. Некоторые аргументы против лямбды в Python:

  • Проблемы с читабельностью
  • Наложение функционального мышления
  • Тяжелый синтаксис с ключевым словом lambda

Несмотря на жаркие дебаты, ставящие под сомнение само существование этой функции в Python, лямбда-функции имеют свойства, которые иногда предоставляют ценность языку Python и разработчикам.

Следующие примеры иллюстрируют сценарии, в которых использование лямбда-функций не только подходит, но и поощряется в коде Python.

Классические функциональные конструкции

Лямбда-функции регулярно используются со встроенными функциями map() и filter(), а также functools.reduce(), представленными в модуле functools. Следующие три примера являются соответствующими иллюстрациями использования этих функций с лямбда-выражениями в качестве компаньонов:

>>> list(map(lambda x: x. upper(), ['cat', 'dog', 'cow']))
['CAT', 'DOG', 'COW']
>>> list(filter(lambda x: 'o' in x, ['cat', 'dog', 'cow']))
['dog', 'cow']
>>> from functools import reduce
>>> reduce(lambda acc, x: f'{acc} | {x}', ['cat', 'dog', 'cow'])
'cat | dog | cow'

Возможно, вам придется встретить код, похожий на приведенные выше примеры, хотя и с более актуальными данными. По этой причине важно распознавать эти конструкции. Тем не менее, эти конструкции имеют эквивалентные альтернативы, которые считаются более Pythonic. В разделе Альтернативы лямбдам вы узнаете, как преобразовывать функции высшего порядка и сопровождающие их лямбды в другие, более идиоматические формы.

Ключевые функции

Ключевые функции в Python — это функции высшего порядка, которые принимают ключ параметра в качестве именованного аргумента. Ключ получает функцию, которая может быть лямбда-выражением. Эта функция напрямую влияет на алгоритм, управляемый самой ключевой функцией. Вот некоторые ключевые функции:

  • sort(): метод списка
  • sorted()min()max(): встроенные функции
  • nlargest() and nsmallest(): в модуле алгоритма очереди кучи heapq

Представьте, что вы хотите отсортировать список идентификаторов, представленных в виде строк. Каждый идентификатор представляет собой объединение идентификатора строки и числа. При сортировке этого списка с помощью встроенной функции sorted() по умолчанию используется лексикографический порядок, поскольку элементы в списке являются строками.

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

>>> ids = ['id1', 'id2', 'id30', 'id3', 'id22', 'id100']
>>> print(sorted(ids)) # Lexicographic sort
['id1', 'id2', 'id30', 'id3', 'id22', 'id100']
>>> sorted_ids = sorted(ids, key=lambda x: int(x[2:])) # Integer sort
>>> print(sorted_ids)
['id1', 'id2', 'id3', 'id22', 'id30', 'id100']

UI Фреймворки

UI фреймворки, такие как Tkinter, wxPython или . NET Windows Forms с IronPython, используют лямбда-функции для отображения действий в ответ на события пользовательского интерфейса.

Простая программа Tkinter, представленная ниже, демонстрирует использование лямбды, назначенной команде кнопки Reverse:

import tkinter as tk
import sys

window = tk.Tk()
window.grid_columnconfigure(0, weight=1)
window.title("Lambda")
window.geometry("300x100")
label = tk.Label(window, text="Lambda Calculus")
label.grid(column=0, row=0)
button = tk.Button(
    window,
    text="Reverse",
    command=lambda: label.configure(text=label.cget("text")[::-1]),
)
button.grid(column=0, row=1)
window.mainloop()

Нажатие кнопки «Reverse» запускает событие, которое запускает лямбда-функцию, изменяя метку с Lambda Calculus на suluclaC adbmaL *:

И wxPython, и IronPython используют одинаковый подход для обработки событий. Обратите внимание, что лямбда-это один из способов обработки событий, но функцию можно использовать для той же цели. В конечном итоге код становится автономным и менее многословным при использовании лямбды, когда объем необходимого кода очень мал.

Интерпритатор Python

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

timeit

В том же духе, что и эксперименты в интерпретаторе Python, модуль timeit предоставляет функции для измерения времени небольших фрагментов кода. В частности, timeit.timeit() может вызываться напрямую, передавая некоторый код Python в строку. Вот пример:

>>> from timeit import timeit
>>> timeit("factorial(999)", "from math import factorial", number=10)
0. 0013087529951008037

Когда инструкция передается в виде строки, timeit() нужен полный контекст. В приведенном выше примере это обеспечивается вторым аргументом, который устанавливает среду, необходимую основной функции для синхронизации. В противном случае возникнет исключение NameError.

Другой подход — использовать лямбду:

>>> from math import factorial
>>> timeit(lambda: factorial(999), number=10)
0.0012704220062005334

Это решение чище, более читабельно и быстрее вводится в интерпретаторе.

Monkey Patching

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

Допустим, вы хотите протестировать функцию, которая во время выполнения обрабатывает случайные значения. Но во время выполнения теста вам нужно повторять предсказуемые значения. В следующем примере показано, как лямбда monkey patching может помочь:

from contextlib import contextmanager
import secrets

def gen_token():
    """Generate a random token."""
    return f'TOKEN_{secrets.token_hex(8)}'

@contextmanager
def mock_token():
    """Context manager to monkey patch the secrets.token_hex
    function during testing.
    """
    default_token_hex = secrets.token_hex
    secrets.token_hex = lambda _: 'feedfacecafebeef'
    yield
    secrets.token_hex = default_token_hex

def test_gen_key():
    """Test the random token."""
    with mock_token():
        assert gen_token() == f"TOKEN_{'feedfacecafebeef'}"

test_gen_key()

Диспетчер контекста помогает изолировать операцию monkey patching функцию из стандартной библиотеки (в этом примере secrets). Лямбда назначенная для secrets.token_hex (), заменяет поведение по умолчанию, возвращая статическое значение.

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

Среды модульного тестирования, такие как unittest и pytest, поднимают эту концепцию на более высокий уровень сложности.

С pytest, все еще использующим лямбда-функцию, тот же пример становится более элегантным и лаконичным:

import secrets

def gen_token():
    return f'TOKEN_{secrets. token_hex(8)}'

def test_gen_key(monkeypatch):
    monkeypatch.setattr('secrets.token_hex', lambda _: 'feedfacecafebeef')
    assert gen_token() == f"TOKEN_{'feedfacecafebeef'}"

С помощью pytest secretts.token_hex() перезаписывается лямбда-выражением, которое будет возвращать детерминированное значение feedfacecafebeef, позволяющее подтвердить правильность теста. monkeypatch позволяет вам контролировать область переопределения. В приведенном выше примере при вызове secretts.token_hex() в последующих тестах без использования monkey patching будет выполняться обычная реализация этой функции.

Выполнение теста pytest дает следующий результат:

$ pytest test_token.py -v
============================= test session starts ==============================
platform linux -- Python 3. 7.2, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
cachedir: .pytest_cache
rootdir: /home/andre/AB/tools/bpython, inifile:
collected 1 item

test_token.py::test_gen_key PASSED                                       [100%]

=========================== 1 passed in 0.01 seconds ===========================

Тест проходит, когда мы проверяем, что gen_token() был выполнен, и результаты были ожидаемыми в контексте теста.

Альтернативы лямбдам

Хотя существуют веские причины для использования лямбды, есть случаи, когда ее использование не одобряется. Так каковы альтернативы?

Функции более высокого порядка, такие как map(), filter() и functools.reduce(), могут быть преобразованы в более элегантные формы с небольшими изменениями, в частности, со списком или генератором выражений.

Map

Встроенная функция map() принимает функцию в качестве первого аргумента и применяет ее к каждому из интерируемых элементов своего второго аргумента. Примерами итерируемых элементов являются строки, списки и кортежи.

map() возвращает итератор, соответствующий преобразованной коллекции. Например, если вы хотите преобразовать список строк в новый список с заглавными буквами, вы можете использовать map() следующим образом:

>>> list(map(lambda x: x.capitalize(), ['cat', 'dog', 'cow']))
['Cat', 'Dog', 'Cow']

Вам необходимо вызвать list() для преобразования итератора, возвращаемого map(), в расширенный список, который можно отобразить в интерпретаторе оболочки Python.

Использование генератора списка исключает необходимость определения и вызова лямбда-функции:

>>> [x. capitalize() for x in ['cat', 'dog', 'cow']]
['Cat', 'Dog', 'Cow']

Filter

Встроенная функция filter(), еще одна классическая функциональная конструкция, может быть преобразована в представление списка. Она принимает предикат в качестве первого аргумента и итеративный список в качестве второго аргумента. Она создает итератор, содержащий все элементы начальной коллекции, удовлетворяющие функции предиката. Вот пример, который фильтрует все четные числа в данном списке целых чисел:

>>> even = lambda x: x%2 == 0
>>> list(filter(even, range(11)))
[0, 2, 4, 6, 8, 10]

Обратите внимание, что filter() возвращает итератор, поэтому необходимо вызывать list, который создает список с заданным итератором.

Реализация, использующая конструкцию генератора списка, дает следующее:

>>> [x for x in range(11) if x%2 == 0]
[0, 2, 4, 6, 8, 10]

Reduce

Начиная с Python 3, Reduce() превратился из встроенной функции в функцию модуля functools. Что касается map() и filter(), его первые два аргумента являются соответственно функцией и итерируемым списком. Он также может принимать инициализатор в качестве третьего аргумента, который используется в качестве начального значения результирующего аккумулятора. Для каждого итерируемого элемента reduce() применяет функцию и накапливает результат, который возвращается, когда итерация исчерпана.

Чтобы применить reduce() к списку пар и вычислить сумму первого элемента каждой пары, вы можете написать так:

>>> import functools
>>> pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
>>> functools. reduce(lambda acc, pair: acc + pair[0], pairs, 0)
6

Более идиоматический подход, использующий выражение генератора в качестве аргумента для sum() в следующем примере:

>>> pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
>>> sum(x[0] for x in pairs)
6

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

>>> pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
>>> sum(x for x, _ in pairs)
6

Использование символа подчеркивания (_) является соглашением Python, указывающим, что вы можете игнорировать второе значение пары.

sum() принимает уникальный аргумент, поэтому выражение генератора не обязательно должно быть в скобках.

Лямбда — это питон или нет?

PEP 8, который является руководством по стилю для кода Python, гласит:

Всегда используйте оператор def вместо оператора присваивания, который связывает лямбду непосредственно с идентификатором. (Источник)

Это правило настоятельно не рекомендует использовать лямбду, привязанную к идентификатору, в основном там, где следует использовать функции. PEP 8 не упоминает другие способы использования лямбды. Как вы видели в предыдущих разделах, лямбды, безусловно, могут найти хорошее применение, хотя они и ограничены.

Возможный способ ответить на этот вопрос заключается в том, что лямбда являются совершенно Pythonic, если нет ничего более доступного Pythonic. Я не буду определять, что означает «Pythonic», оставив вас с определением, которое лучше всего подходит для вашего мышления, а также для вашего личного стиля или стиля кодирования вашей команды.

Заключение

Теперь вы знаете, как использовать лямбды в Python и можете:

  • Написать лямбду и использовать анонимные функции
  • Мудро выбирать между лямбдами или обычными функциями
  • Избегать чрезмерного использования лямбд
  • Использовать лямбды с функциями высшего порядка или ключевыми функциями Python

Если у вас есть склонность к математике, вы можете повеселиться, исследуя увлекательный мир лямбда-исчисления (lambda calculus).

Python лямбды подобны соли. Щепотка соли улучшит вкус, но слишком много испортит блюдо.

Оригинальная статья:  Andre Burgaud  How to Use Python lambda Functions

Была ли вам полезна эта статья?


Лямбда-выражения . Изучай Haskell во имя добра!

Лямбда-выражения – это анонимные функции, которые используются, если некоторая функция нужна нам только однажды. Как правило, мы создаём анонимные функции с единственной целью: передать их функции высшего порядка в качестве параметра. Чтобы записать лямбда-выражение, пишем символ (напоминающий, если хорошенько напрячь воображение, греческую букву лямбда – ?), затем записываем параметры, разделяя их пробелами. Далее пишем знак –> и тело функции. Обычно мы заключаем лямбду в круглые скобки, иначе она продолжится до конца строки вправо.

Если вы обратитесь к примеру, приведённому в предыдущем разделе, то увидите, что мы создали функцию isLong в секции where функции numLongChains только для того, чтобы передать её в фильтр. Вместо этого можно использовать анонимную функцию:

numLongChains :: Int

numLongChains = length (filter (xs –> length xs > 15) (map chain [1..100]))

Анонимные функции являются выражениями, поэтому мы можем использовать их таким способом, как в примере. Выражение (xs –> length xs > 15) возвращает функцию, которая говорит нам, больше ли 15 длина переданного списка.

Те, кто не очень хорошо понимает, как работает каррирование и частичное применение функций, часто используют анонимные функции там, где не следует. Например, выражения map (+3) [1,6,3,2] и map (x –> x + 3) [1,6,3,2] эквивалентны, так как (+3) и (x –> x + 3) – это функции, которые добавляют тройку к аргументу. Излишне говорить, что использование анонимной функции в этом случае неоправданно, так как частичное применение значительно легче читается.

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

ghci> zipWith (a b –> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]

[153.0,61.5,31.0,15.75,6.6]

По аналогии с обычными функциями, можно выполнять сопоставление с образцом в лямбда-выражениях. Единственное отличие в том, что нельзя определить несколько образцов для одного параметра – например, записать для одного параметра образцы [] и (x: xs) и рассчитывать, что выполнение перейдёт к образцу (x:xs) в случае неудачи с []. Если сопоставление с образцом в анонимной функции заканчивается неудачей, происходит ошибка времени выполнения, так что поосторожнее с этим!

ghci> map ((a,b) –> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]

[3,8,9,8,7]

Обычно анонимные функции заключаются в круглые скобки, если только мы не хотим, чтобы лямбда-выражение заняло всю строку. Интересная деталь: поскольку все функции каррированы по умолчанию, допустимы две эквивалентные записи.

addThree :: Int -> Int -> Int -> Int

addThree x y z = x + y + z

addThree’ :: Int -> Int -> Int -> Int

addThree’ = x -> y -> z -> x + y + z

Если мы объявим функцию подобным образом, то станет понятно, почему декларация типа функции представлена именно в таком виде. И в декларации типа, и в теле функции имеются три символа –>. Конечно же, первый способ объявления функций значительно легче читается; второй – это всего лишь очередная возможность продемонстрировать каррирование.

ПРИМЕЧАНИЕ. Обратите внимание на то, что во втором примере анонимные функции не заключены в скобки. Когда вы пишете анонимную функцию без скобок, предполагается, что вся часть после символов –> относится к этой функции. Так что пропуск скобок экономит на записи. Конечно, ничто не мешает использовать скобки, если это вам больше нравится.

Тем не менее есть случаи, когда использование такой нотации оправдано. Я думаю, что функция flip будет лучше читаться, если мы объявим её так:

flip’ :: (a –> b –> c) –> b –> a –> c

flip’ f = x y –> f y x

Несмотря на то что эта запись равнозначна flip’ f x y = f y x, мы даём понять, что данная функция чаще всего используется для создания новых функций. Самый распространённый сценарий использования flip – вызов её с некоторой функцией и передача результирующей функции в map или zipWith:

ghci> zipWith (flip (++)) [«люблю тебя», «любишь меня»] [«я «, «ты «]

[«я люблю тебя»,»ты любишь меня»]

ghci> map (flip subtract 20) [1,2,3,4]

[19,18,17,16]

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

Анонимные функции | Python: Функции

Иногда нам нужна функция, чтобы её передать куда-то (в функцию высшего порядка), но больше эта функция нигде не понадобится. Как вы можете знать, придумывание имён в программировании — одна из основных проблем. Но если функция нужна здесь и сейчас, а больше нигде её вызывать не придётся, то и имя такой функции не нужно! Такие одноразовые функции позволяют описывать практически все языки, умеющие работать с функциями как со значениями. В Python определение подобной одноразовой функции выглядит так:

>>> lambda x: x + 1
<function <lambda> at 0x7f56e5798a60>

Мы сконструировали функцию, но имя она не получила, поэтому REPL её отобразил, как function <lambda>.

Ключевое слово lambda названо в честь лямбда абстракции — основного кирпичика Лямбда Исчисления, математического аппарата, часто применяющегося в разработке языков программирования. В Лямбда Исчислении все функции — анонимные, поэтому анонимные функции во многих языках тоже иногда называют «лямбдами» или «лямбда-функциями».

Рассмотрим пример, использующий анонимную функцию:

>>> l = [1, 2, 5, 3, 4]
>>> l.sort(key=lambda x: -x)
>>> l
[5, 4, 3, 2, 1]

Метод sort принимает в качестве аргумента key ссылку на функцию. В примере в качестве аргумента указана функция, меняющая знак у аргумента — поэтому список получается отсортирован от большего к меньшему. Сортировка с указанием ключа сама по себе встречается довольно часто, а вот ключи сортировки чаще всего будут разными. Поэтому выносить ключи в именованные функции смысла нет и анонимные функции здесь подходят идеально!

Особенности анонимных функций

Вы могли заметить, что аргументы анонимных функций не заключены в скобки. К этому нужно будет привыкнуть. Остальные средства для описания аргументов доступны в полной мере — и именованные аргументы, и *args с **kwargs.

А ещё вы могли обратить внимание на то, что в примерах функции явно что-то возвращают, но слово return нигде не указано! Дело в том, что тело лямбда-функции — это всегда одно выражение, результат вычисления которого и будет возвращаемым значением. Да, в теле лямбда-функции не получится выполнить несколько действий и не получится использовать многострочные конструкции вроде for и while. Но зато анонимные функции обычно просто читать, чего было бы сложно добиться, разреши авторы «многострочные» лямбды.

Ещё одна особенность лямбда-функций заключается в том, что само объявление функции является выражением! Функции можно конструировать и тут же вызывать, не заканчивая выражение:

>>> 1 + (lambda x: x * 5)(8) + 1
42

Этот пример выглядит забавно, но именно в таком виде лямбды встречаются редко. Зато часто можно встретить возврат лямбды из функции:

>>> def caller(arg):
...     return lambda f: f(arg)
. ..
>>> call_with_five = caller(5)
>>> call_with_five(str)
'5'
>>> call_with_five(lambda x: x + 1)
6

Настройка подписи кода для AWS Lambda

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

Функции, определенные как образы контейнеров, не поддерживают подписывание кода.

Чтобы проверить целостность кода, используйте AWS Signer для создания пакетов кода с цифровой подписью для функции и слои.Когда пользователь пытается развернуть пакет кода, Lambda выполняет проверки кода. package перед принятием развертывания. Поскольку проверки подписи кода выполняются во время развертывания, влияние производительности на выполнение функции.

Вы также используете AWS Signer для создания профилей подписи . Вы используете профиль подписи для создания пакет подписанного кода. Используйте AWS Identity and Access Management (IAM), чтобы контролировать, кто может подписывать пакеты кода, и создавать профили подписи.Дополнительные сведения см. в разделе Аутентификация и управление доступом в Руководстве разработчика AWS Signer .

Чтобы включить подпись кода для функции, вы создаете конфигурацию подписи кода и прикрепляете это к функции. Конфигурация подписи кода определяет список разрешенных профилей подписи и действие политики. принять, если какая-либо из проверок не пройдена.

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

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

Вы можете настроить подпись кода, чтобы регистрировать изменения в AWS CloudTrail.Успешные и заблокированные развертывания в функциях регистрируется в CloudTrail с информацией о проверке подписи и проверке.

Вы можете настроить подпись кода для своих функций с помощью консоли Lambda, интерфейса командной строки AWS (AWS CLI), AWS CloudFormation и Модель бессерверных приложений AWS (AWS SAM).

Дополнительная плата за использование AWS Signer или подписывание кода для AWS Lambda не взимается.

Проверка подписи

Lambda выполняет следующие проверки при развертывании подписанного пакета кода в вашей функции:

  1. Целостность — подтверждает, что пакет кода не был изменен с момента его подписания. лямбда сравнивает хэш пакета с хешем из подписи.

  2. Срок действия — проверяет, не истек ли срок действия подписи пакета кода.

  3. Несоответствие — проверяет, что пакет кода подписан одним из разрешенных профилей подписи для лямбда-функция. Несоответствие также возникает, если подпись отсутствует.

  4. Отзыв — подтверждает, что подпись пакета кода не была отозвана.

Политика проверки подписи, определенная в конфигурации подписи кода, определяет, какие из следующих действия, которые Lambda предпринимает, если какая-либо из проверок не пройдена:

  • Предупреждение — Lambda разрешает развертывание пакета кода, но выдает предупреждение. Lambda выпускает новый метрике Amazon CloudWatch, а также сохраняет предупреждение в журнале CloudTrail.

  • Enforce — Lambda выдает предупреждение (то же, что и для действия Warn) и блокирует развертывание пакет кода.

Вы можете настроить политику для проверки истечения срока действия, несоответствия и отзыва. Обратите внимание, что вы не можете настроить политика проверки целостности. Если проверка целостности не пройдена, Lambda блокирует развертывание.

Необходимые условия конфигурации

Прежде чем настраивать подпись кода для функции Lambda, используйте AWS Signer для выполнения следующих действий:

Дополнительные сведения см. в разделе Создание профилей подписи (консоль) в Руководстве разработчика AWS Signer .

Создание конфигураций подписи кода

Конфигурация подписи кода определяет список разрешенных профилей подписи и проверку подписи. политика.

Для создания конфигурации подписи кода (консоль)

  1. Откройте настройки подписи кода страница консоли Lambda.

  2. Выберите Создать конфигурацию .

  3. Для Описание введите описательное имя конфигурации.

  4. В разделе Профили подписи добавьте в конфигурацию до 20 профилей подписи.

    1. Для версии профиля подписи ARN выберите имя ресурса Amazon для версии профиля. (ARN) или введите ARN.

    2. Чтобы добавить дополнительный профиль подписи, выберите Добавить профили подписи .

  5. В разделе Политика проверки подписи выберите Предупредить или Применить .

  6. Выберите Создать конфигурацию .

Обновление конфигурации подписи кода

Когда вы обновляете конфигурацию подписи кода, изменения влияют на будущие развертывания функций, которые конфигурация подписи кода прилагается.

Для обновления конфигурации подписи кода (консоль)

  1. Откройте настройки подписи кода страница консоли Lambda.

  2. Выберите конфигурацию подписи кода для обновления, а затем выберите Изменить .

  3. Для Описание введите описательное имя конфигурации.

  4. В разделе Профили подписи добавьте в конфигурацию до 20 профилей подписи.

    1. Для версии профиля подписи ARN выберите имя ресурса Amazon для версии профиля. (ARN) или введите ARN.

    2. Чтобы добавить дополнительный профиль подписи, выберите Добавить профили подписи .

  5. В разделе Политика проверки подписи выберите Предупредить или Применить .

  6. Выберите Сохранить изменения .

Удаление конфигурации подписи кода

Вы можете удалить конфигурацию подписи кода, только если ее не используют никакие функции.

Удаление конфигурации подписи кода (консоль)

  1. Откройте настройки подписи кода страница консоли Lambda.

  2. Выберите конфигурацию подписи кода для удаления, а затем выберите Удалить .

  3. Для подтверждения снова выберите Удалить .

Включение подписи кода для функции

Чтобы включить подписывание кода для функции, вы связываете конфигурацию подписывания кода с функцией.

Чтобы связать конфигурацию подписи кода с функцией (консолью)

  1. Откройте страницу «Функции» консоли Lambda.

  2. Выберите функцию, для которой вы хотите включить подпись кода.

  3. В разделе Конфигурация подписи кода выберите Изменить .

  4. В Изменить подпись кода выберите конфигурацию подписи кода для этой функции.

  5. Выберите Сохранить .

Настройка политик IAM

Чтобы предоставить пользователю разрешение на доступ к API подписи кода операций, прикрепите одно или несколько утверждений политики к пользовательской политике. Для получения дополнительной информации о пользователе политики, см. Политики IAM на основе удостоверений для Lambda.

Следующий пример инструкции политики предоставляет разрешение на создание, обновление и получение подписи кода. конфигурации.

  {
  «Версия»: «2012-10-17»,
  "Заявление": [
    {
      «Эффект»: «Разрешить»,
      "Действие": [
          "лямбда:CreateCodeSigningConfig",
          "лямбда:UpdateCodeSigningConfig",
          "лямбда: GetCodeSigningConfig"
        ],
      "Ресурс": "*"
    }
  ]
}  

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

Следующий пример инструкции политики предоставляет разрешение на создание функции. Заявление о политике включает lambda:CodeSigningConfigArn Условие для указания разрешенной конфигурации подписи кода. лямбда блокирует любой запрос API CreateFunction , если его параметр CodeSigningConfigArn отсутствует или не соответствует значению в условии.

  {
  «Версия»: «2012-10-17»,
  "Заявление": [
    {
      "Sid": "AllowReferencingCodeSigningConfig",
      «Эффект»: «Разрешить»,
      "Действие": [
          "лямбда: Создать функцию",
        ],
      "Ресурс": "*",
      "Состояние": {
          "StringEquals": {
              "лямбда:CodeSigningConfigArn":
                  «arn:aws:lambda:us-west-2:123456789012:code-signing-config:csc-0d4518bd353a0a7c6»
          }
      }
    }
  ]
}  

Настройка подписи кода с помощью Lambda API

Для управления конфигурациями подписи кода с помощью AWS CLI или AWS SDK используйте следующие операции API:

Чтобы управлять конфигурацией подписи кода для функции, используйте следующие операции API:

Подписание лямбда-кода

AWS.

В этом блоге я расскажу вам о… | Винодкумар Мандалапу

В этом блоге я расскажу вам о подписи кода для AWS Lambda. Это контроль доверия и целостности, который помогает администраторам обеспечивать выполнение только подписанных пакетов кода в их функциях Lambda и что код не был изменен с тех пор подписание.

Подписание кода для AWS Lambda использует AWS Signer, полностью управляемый сервис подписи кода от AWS

Для начала необходимо создать профиль подписывающей стороны (убедитесь, что у вас есть необходимые права доступа для создания профиля подписывающей стороны).

Чтобы создать профиль подписи, перейдите в раздел «Подписывающий» → нажмите «Создать профиль подписи». создание профиля

Вы можете настроить свои функции для использования подписи кода через консоль AWS Lambda, интерфейс командной строки (CLI) или API, создав и присоединив к функции новый ресурс под названием «Конфигурация подписи кода». Теперь перейдите в консоль лямбда и нажмите «Создать конфигурацию»

Конфигурация подписи кода

Нажмите «Создать конфигурацию» и выберите необходимые сведения, как показано ниже, а затем нажмите «Создать конфигурацию»

Конфигурация подписи кода

Кроме того, вы можете установить политику проверки подписи на «Предупреждать» или «Принудительно».

При использовании параметра «Предупреждение» Lambda регистрирует метрику наблюдения за облаком в случае сбоя проверки подписи, но принимает развертывание.

При использовании параметра «Принудительно» Lambda отклоняет развертывание в случае сбоя проверки подписи.

Один раз После создания профиля подписи и конфигураций подписи Теперь мы можем использовать профили подписавших и будем использовать задания подписи и убедиться, что развернут только подписанный пакет.

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

  1. Сразу после добавления конфигурации подписи кода в вашу лямбда-функцию она отключит редактирование встроенного кода для этой функции, независимо от того, насколько она мала. лямбда-функция , Для E.g., посмотрите на приведенный ниже снимок экрана для справки

2. Для приведенной выше лямбда-функции теперь я добавлю профиль подписи, G на вкладку «Конфигурация» → выберите подпись кода → нажмите «Изменить» → и выберите конфигурацию подписи кода, которую вы создали и нажмите «Сохранить»

. После настройки подписи кода, как показано выше, вы можете увидеть, что встроенное редактирование кода отключено для этой функции.

На данный момент мы завершили шаг 2, как подписывание кода помогает нам отключить редактирование встроенного кода. Теперь нам нужно посмотреть, как развертывать только подписанные пакеты и как lambda будет запрещать развертывание неподписанных пакетов.

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

Сначала вам нужно выбрать профиль подписи, который вы хотите использовать

А затем в разделе «Расположение источника кода» вам нужно выбрать расположение корзины S3, где находится ваш исходный код для лямбда-функции (в этом случае она находится в корзине signerwm, и убедитесь, что в корзине включено управление версиями, что является обязательным, потому что вам нужно выберите версию объекта)

И в URL-адресе S3 вам нужно указать место, где будет создан ваш подписанный пакет (в этом случае это то же ведро, но в другой папке)

После того, как все детали заполнены, нажмите «Начать задание» и то Теперь вы можете видеть, что подписанный пакет с именем идентификатора задания будет сгенерирован в подписанной папке

Теперь для правильного развертывания лямбда-функции нам нужно развернуть только этот подписанный пакет, тогда только функция лямбда примет развертывание, иначе развертывание завершится ошибкой.

Теперь давайте сначала попробуем развернуть неподписанный пакет, а затем развернем подписанный пакет, чтобы проверить, как это работает.

Теперь я разверну неподписанный пакет из корзины s3 с zip-файлом, который у меня есть. Теперь к функции Lambda и выберите загрузку из, вы можете выбрать местоположение s3 или zip-файл. Теперь я выбираю выбор s3, который имеет обычный zip-файл

Как вы видели на снимке экрана выше, вы получите сообщение об ошибке, когда пытаетесь развернуть обычный неподписанный zip-файл. Теперь я выберу подписанный пакет, который был сгенерирован при запуске задания подписи, а затем развернется в lambda

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

В соответствии с приведенными выше настройками и развертыванием я показал вам процесс ручного развертывания, как можно использовать подписывающую сторону, чтобы понять, как подписывающая сторона работает с лямбдой. Но обычно нам нужно делать это в конвейере CI/CD с помощью команд CLI.

Чтобы подписать zip-файл после упаковки и перед развертыванием, вы можете использовать приведенную ниже команду

aws signer start-signing-job — source ‘s3={bucketName=signerwm,key=Ami-Create.py.zip, version= null}’ — пункт назначения ‘s3={bucketName=signerwm,prefix=signed/}’ — имя-профиля Jenkinswm — регион ap-south-1 | jq -r ‘.jobId’

Приведенная выше команда даст вам имя zip-файла, и вы можете передать его в качестве переменной для развертывания этого zip-файла. Конвейер CI/CD. Это гарантирует, что будет развернут только подписанный код, полученный из надежного источника.

Мы можем даже ограничить редактирование встроенного кода.

На данный момент это все, что касается блога подписанта AWS. Любые комментарии или предложения по этому поводу будут высоко оценены

Знак лямбда: саркоидоз | Архив Бронконевмологии

Archivos de Bronconeumologia — это научный журнал, который преимущественно публикует перспективные оригинальные исследовательские статьи, содержание которых основано на результатах, касающихся нескольких аспектов респираторных заболеваний, таких как эпидемиология, патофизиология, клиника, хирургия и фундаментальные исследования. В журнале также публикуются другие типы статей, такие как обзоры, редакционные статьи, несколько специальных статей, представляющих интерес для общества и редакции, научные письма, письма в редакцию и клинические изображения. Это ежемесячный журнал, который публикует в общей сложности 12 выпусков и несколько приложений, содержащих статьи, относящиеся к различным разделам.

Все рукописи, поступившие в журнал, оцениваются редакторами и отправляются на экспертную рецензию, а обработка осуществляется редактором и/или заместителем редактора из группы.Журнал выходит ежемесячно на испанском и английском языках. Поэтому приветствуются рукописи, написанные на испанском или английском языках. Переводчики, работающие в журнале, отвечают за соответствующие переводы.

Рукописи будут представлены в электронном виде с использованием следующего веб-сайта: https://www.editorialmanager.com/ARBR/, ссылка на который также доступна на главной веб-странице Archivos de Bronconeumologia.

Доступ к любой опубликованной статье на любом языке возможен через веб-страницу журнала, а также из PubMed, Science Direct и других международных баз данных. Кроме того, журнал также присутствует в Twitter и Facebook. Журнал выражает мнение Испанского респираторного общества пульмонологии и торакальной хирургии (SEPAR), а также других научных обществ, таких как Латиноамериканское торакальное общество (ALAT) и Иберийско-американская ассоциация торакальной хирургии (AICT).

Авторы также могут отправлять свои статьи в сопутствующее название журнала с открытым доступом, Open Respiratory Archives .

Бессерверная подпись кода с помощью AWS Lambda и AWS Signer

Несколько недель назад Linux Foundation и партнеры объявили о проекте sigstore — некоммерческой службе подписи программного обеспечения.Недавние проблемы безопасности Solarwind показали, что крайне важно защитить цепочку поставок программного обеспечения от несанкционированных изменений. Поскольку безопасность является важной частью любого приложения, разработчики и организации должны следовать рекомендациям безопасного жизненного цикла разработки программного обеспечения (SSDLC) . Взломщики Solarwinds возродили интерес к SSLDC и конвейеру разработки программного обеспечения.

Вкратце, SSDCL состоит из 5 фаз:

    1. Требования
    2. Дизайн
    3. Разработка
    4. Проверка/тестирование
    5. Развертывание

 

В этой записи блога мы рассмотрим AWS Signer и то, как он может помочь с , фаза 5 — развертывание, в бессерверной среде с AWS Lambda.

 

AWS Signer и подписывание кода

 

> AWS Signer — это полностью управляемый сервис подписи кода, обеспечивающий надежность и целостность вашего кода. Организации проверяют код с помощью цифровой подписи, чтобы убедиться, что код не изменен и получен от доверенного издателя. источник

Так что же такое подпись кода? Подписание кода — это процесс применения цифровой подписи к артефактам программного обеспечения. Это обеспечивает уровень доверия, что код не был изменен с момента публикации.Подпись кода помогает доказать:

  • Источник контента: Подпись кода указывает, что программное обеспечение или приложение поступает из определенного источника, в данном случае AWS Signer.
  • Целостность содержимого: Подпись кода гарантирует, что код не был изменен или подделан.
  • Лучшее в AWS Signer? Это бесплатно.

 

Конфигурация подписи кода

для AWS Lambda

 

> Конфигурация подписи кода определяет список разрешенных профилей подписи и определяет политику проверки подписи кода.источник

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

  • AllowedPublishers: Профили подписи, которые могут использовать конфигурацию подписи кода.
  • UntrustedArtifactOnDeployment: Это может быть либо Enforce , либо Warn . Если для политики установлено значение Enforce, Lambda заблокирует развертывание, если проверка подписи завершится неудачно.Если установлено значение Предупреждать , Lambda разрешает развертывание и создает журнал Cloudwatch (доступный для просмотра в Cloudwatch Metrics).

 

Исходный код

 

Вы можете найти весь исходный код для примеров в этом блоге в этом репозитории Github.

Используются следующие инструменты:

  • AWS CDK : CDK используется для быстрой загрузки некоторой инфраструктуры.
  • AWS CLI : мы используем AWS CLI, чтобы начать подписывание заданий, создавать функции и развертывать код.Это то, что должно быть автоматизировано в конвейере, но для этого поста упрощено.
  • Nodejs : поскольку приложение CDK написано на Typescript

Ваша локальная среда должна быть настроена для развертывания инфраструктуры, созданной CDK, и выполнения команд в интерфейсе командной строки AWS.

Вам, наверное, интересно, почему мы не создаем лямбда-функцию с помощью CDK. Для демонстрации мы настроим конфигурацию подписи кода на Enforce .Это означает, что создать AWS Lambda без подписанного пакета кода не удастся. В настоящее время эта функция не поддерживается в CDK «из коробки», поэтому нам придется управлять ресурсом с помощью интерфейса командной строки AWS. Если бы мы настроили конфигурацию подписи кода с Warn, , то мы могли бы использовать CDK для развертывания лямбды.

 

Что нам нужно?

 

  1. Версии Корзина S3: AWS Signer хранит свои подписанные артефакты в ** версии** корзины S3.
  2. Профиль подписывающего лица: профиль подписывающего лица AWS, который будет использоваться для подписи артефактов программного обеспечения
  3. .
  4. Конфигурация подписи кода: эта конфигурация подписи кода использует профиль AWS Signer и будет связана с функцией Lambda.
  5. Учетные данные для выполнения подписи кода с вашего терминала.

 

Подписание и проверка кода в действии

 

Создав инфраструктуру, мы начнем с создания функции Lambda и прикрепим конфигурацию подписи кода, которую мы создали с помощью CDK.Убедитесь, что вы загрузили образец кода в корзину с версиями, так как мы развернем его позже. Вы можете найти zip-файл в репозитории с примерами в папке «function».

Теперь давайте посмотрим на операторы IAM для развертывания лямбды. Конфигурация подписи кода поддерживает `Условие`[Условие](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awslambda.html) в политиках IAM. Это можно использовать для принудительного создания и обновления новых лямбда-выражений с использованием конфигурации подписи кода.

        {

            "Условие": {

               "StringEquals": {

                   "лямбда:CodeSigningConfigArn": [

                       "arn:aws:lambda:::code-signing-config:csc-"

                   ]

                }

            },

            "Действие": [

               "лямбда:CreateFunction",

               "lambda:PutFunctionCodeSigningConfig"

            ],

            "Ресурс": "*",

            "Эффект": "Разрешить"

        }

Приведенная выше политика блокирует все попытки создания функции Lambda без конфигурации подписи кода, указанной в политике. Давайте попробуем создать лямбду:

лямбда-функция создания aws \

    --имя-функции "кодовая-подписанная-функция" \

    --среда выполнения "nodejs14.x" \

    --role <лямбда-роль> \

    --code S3Bucket=,S3Key=, S3ObjectVersion=<версия> \

     --handler index.handler \ 

    --code-signing-config-arn

При выполнении вышеуказанной команды мы, как и ожидалось, получили ошибку.

Произошла ошибка (CodeVerificationFailedException) при вызове операции CreateFunction: Lambda не может развернуть функцию. Функция или уровень могут быть подписаны с использованием подписи, которую клиент не настроен принимать. Проверьте предоставленную подпись для функции с кодовой подписью

.

Это означает, что нам нужно сначала подписать наш код.

Давайте кратко рассмотрим минимальные политики IAM для запуска задания подписи кода.

        {

            "Действие": [

               "s3:GetObjectVersion",

               "s3:PutObject",

               "s3:ListBucket"

            ],

           "Ресурс": [

               "arn:aws:s3:::<имя_сегмента>/*",

               "arn:aws:s3:::<имя_сегмента>"

            ],

            "Эффект": "Разрешить"

        },

        {

            "Действие": [

               "signer:GetSigningProfile",

               "signer:StartSigningJob"

            ],

           "Ресурс": "arn:aws:signer:::/signing-profiles/",

            "Эффект": "Разрешить"

        }

При правильной настройке теперь у нас есть разрешения на запуск задания подписи кода. Мы скажем AWS Signer поместить все наши подписанные артефакты в папку `/signed` в корзине S3.

Запуск задания с помощью интерфейса командной строки AWS довольно прост и понятен, и его можно выполнить с помощью следующей команды:

aws signer start-signing-job \ 

--source 's3={bucketName=<лямбда-бакет>, version=<строка-версии>, key=}' \

--destination 's3={bucketName=<лямбда-бакет>, префикс=signed/" \

--profile-name

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

А как же обновления? Попытка обновить функцию без пакета развертывания с подписью кода вызовет следующую ошибку:

.

Произошла ошибка (CodeVerificationFailedException) при вызове операции UpdateFunctionCode: Lambda не может развернуть функцию. Функция или уровень могут быть подписаны с использованием подписи, которую клиент не настроен принимать.Проверьте предоставленную подпись

Таким образом, при обновлении кода функции требуется тот же рабочий процесс, что и для создания лямбда-функции. Это гарантирует, что все развернутые артефакты кода будут подписаны.

 

Резюме

 

При правильных операторах IAM создание Lambda может пройти только при создании с определенной конфигурацией подписи кода

Конфигурация подписи кода может обеспечить, чтобы все артефакты развертывания Lambda были подписаны кодом с помощью AWS Signer.

В этом посте показано, как защитить бессерверные приложения с помощью AWS Signer в качестве управляемого сервиса подписи кода в сочетании с конфигурацией подписи кода для AWS Lambda. Как при создании функций Lambda, так и при их обновлениях проверяется подпись кода.

Это недавнее событие – пример намеренного внедрения вредоносного кода в пакет NPM, поэтому имейте в виду, что само по себе подписание кода не защищает от всех вредоносных атак, а подписание кода – это всего лишь один шаг в процессе SSDLC. Таким образом, надлежащая проверка кода и его зависимостей по-прежнему требуется, прежде чем он будет подписан.

Лямбда-симптом или признак твин-пик в 6 недель беременности (слева) и 13…

… Однако в литературе у дихориальных близнецов было описано несколько случаев ФФФТ, один случай возможного TAPS, один случай описано акардиальное двойникование. [5][6][7][8][9][10][11] [12] [13][14][15] Кроме того, были проведены исследования, обнаружившие наличие сосудистых анастомозов в дихориальные плаценты.16,17 Важна своевременная диагностика TAPS. …

… Наш случай демонстрирует возможное возникновение TAPS у близнецов с DCDA и побудил к обзору литературы, который выявил один случай вероятного TAPS, 15 один случай акардиального близнеца и несколько тематических исследований TTTS при DCDA. двойняшки. [5][6][7][8][9][10][11] [12] [13][14][15] Единственный случай TAPS, диагностированный у близнецов DCDA, насколько нам известно в литературе. был Zillox et al. Описан случай TAPS, который развился на 31-й неделе гестации у близнецов, у которых в первом триместре был диагностирован дихориальный синдром, подтвержденный гистопатологией плаценты….

… Среди случаев TTTS, TAPS и акардиального близнеца, обнаруженных в литературе, которые тестировали на зиготность, все близнецы были протестированы постнатально, и все продемонстрировали монозиготность. 8,9, 12, 13 Поэтому мы предлагаем, чтобы в случаях близнецов DCDA, у которых на УЗИ выявляется картина, наводящая на мысль о TTTS/TAPS, антенатально следует рассмотреть возможность анализа бесклеточной ДНК на зиготность. Неинвазивное дородовое тестирование (NIPT) в настоящее время коммерчески доступно для проверки на зиготность одним поставщиком; однако мы ожидаем, что в ближайшем будущем появятся и другие поставщики….

В литературе, хотя и редко, приводятся доказательства того, что сосудистые анастомозы встречаются у дихориальных близнецов. Таким образом, близнецовую анемию с последовательностью полицитемии следует рассматривать как дифференциальный диагноз у дихориальных близнецов, если есть подозрение на антенатальное УЗИ. Хотя это редкость, в литературе имеются доказательства того, что сосудистые анастомозы встречаются у дихориальных близнецов. Таким образом, близнецовую анемию с последовательностью полицитемии следует рассматривать как дифференциальный диагноз у дихориальных близнецов, если есть подозрение на антенатальное УЗИ.

Трансфузионный синдром от двух близнецов (TTTS) является серьезным осложнением, типичным для монохориальной беременности. Описаны случаи дихориальной беременности. Авторы представляют отчет о предполагаемом TTTS при дихориальной беременности, наблюдаемой в нашем учреждении, когда пациентка поступила в отделение неотложной помощи на 31 4/7 неделе беременности с жалобами на отсутствие движений плода. У обоих плодов сердечной деятельности не было. У первого близнеца присутствовало маловодие и его мочевой пузырь не визуализировался, а у второго близнеца визуализировались многоводие и увеличенный мочевой пузырь.Патологические данные плодов были совместимы с диагнозом TTTS, а исследование плаценты подтвердило наличие дихориальной/диамниотической плаценты с поверхностными сосудами, пересекающими разделяющую мембрану.

Das Management einer Zwillingsschwangerschaft beginnt mit der korrekten Beurteilung der Chorion- und Amnionverhältnisse bereits beim Ultraschall im ersten Trimester. Es gibt zahlreiche Unterschiede zwischen Einlings- und Zwillingsplazenten. Während dichoriale Plazenten denen von Einlingen ähneln können, unterscheiden sich monochoriale Plazenten davon grundsätzlich.Das Verständnis der Architektur von Zwillingsplazenten ist entscheidend, um den Mechanismen der Pathologien zu verstehen. In diesem Kapitel werden die Unterschiede zwischen monochorialen und dichorialen Plazenten näher erläutert. Weiterhin wird die Bedeutung und Pathologie der Plazenta beim Zwillingstransfusionssyndrom und beim discordanten Zwillingswachstum erläutert.

Передовой опыт и расширенные шаблоны для подписи кода Lambda

Amazon Web Services (AWS) недавно выпустила функцию подписи кода для AWS Lambda.С помощью этой функции вы можете обеспечить целостность своих артефактов кода и убедиться, что только доверенные разработчики могут развертывать код для ваших функций AWS Lambda. Сегодня давайте рассмотрим базовый вариант использования, а также лучшие практики подписи лямбда-кода. Затем давайте углубимся и поговорим о двух расширенных шаблонах: один для централизованной подписи и один для проверки на уровне нескольких учетных записей. Вы можете использовать эти расширенные шаблоны для использования подписи кода в модели распределенного владения, где у вас есть отдельные группы для разработчиков, пишущих код, и для групп, ответственных за применение определенных профилей подписи или за публикацию слоев.

Безопасный жизненный цикл разработки программного обеспечения

В контексте того, что дает эта возможность, давайте рассмотрим безопасный жизненный цикл разработки программного обеспечения (SDLC). Вам нужны различные виды контроля безопасности для каждого из этапов разработки. Обзор этапов разработки безопасного SDLC — кода, сборки, тестирования, развертывания и мониторинга — вместе с применимыми элементами управления безопасностью можно найти на рис. 1. Вы можете использовать подпись кода для Lambda, чтобы защитить этап развертывания и дать криптографическую защиту. сильная проверка хэша.

Рисунок 1: Подписание кода обеспечивает проверку хэша на этапе развертывания безопасного SDLC

Добавление безопасности в DevOps и реализация DevSecOps с помощью AWS CodePipeline содержат дополнительную информацию о создании безопасного SDLC, уделяя особое внимание элементам управления анализа кода.

Базовая модель:

На рис. 2 показан базовый шаблон, описанный в разделе Подписание кода для AWS Lambda и в документации. Базовый шаблон подписи кода использует AWS Signer для ZIP-файла и вызывает API создания для установки подписанного артефакта в Lambda.

Рисунок 2: Базовый шаблон подписи кода

Основной шаблон, показанный на рис. 2, выглядит следующим образом:

  1. Администратор создает профиль подписи в AWS Signer. Профиль подписи аналогичен сертификату подписи кода и представляет собой идентификатор издателя. Администраторы могут предоставить разработчикам доступ через AWS Identity and Access Management (IAM), чтобы они могли использовать профиль подписи для подписи своих артефактов.
  2. Администраторы создают конфигурацию подписи кода (CSC) — новый ресурс в Lambda, определяющий профили подписи, которым разрешено подписывать код, и политику проверки подписи, которая определяет, следует ли предупреждать или отклонять развертывания, не прошедшие проверку подписи.CSC можно присоединить к существующим или новым функциям Lambda, чтобы включить проверку подписи при развертывании.
  3. Разработчики используют один из разрешенных профилей подписи для подписи артефакта развертывания — ZIP-файла — в AWS Signer.
  4. Разработчики развертывают подписанный артефакт развертывания в функцию с помощью API CreateFunction или API UpdateFunctionCode.

Lambda выполняет проверку подписи перед принятием развертывания. Развертывание завершается неудачей, если проверка подписи не удалась, и вы установили политику проверки подписи в CSC, чтобы отклонить развертывание с использованием режима ENFORCE.

Проверка подписи кода

Подпись кода для Lambda обеспечивает четыре проверки подписи. Во-первых, проверка целостности подтверждает, что артефакт развертывания не был изменен после того, как он был подписан с помощью AWS Signer. Lambda выполняет эту проверку, сопоставляя хэш артефакта с хешем из подписи. Вторая проверка — это проверка на несоответствие источника , которая определяет, отсутствует ли подпись или артефакт подписан профилем подписи, который не указан в CSC.Третья, проверка срока действия , завершится ошибкой, если срок действия подписи истек. Четвертый — проверка отзыва , которая используется для проверки того, не пометил ли кто-либо явным образом профиль подписи, используемый для подписи, или задание подписи как недействительное, отменив его.

Проверка целостности должна завершиться успешно, иначе Lambda не запустит артефакт. Остальные три проверки можно настроить так, чтобы либо блокировать вызов, либо генерировать предупреждение. Эти проверки выполняются по порядку до тех пор, пока одна проверка не завершится ошибкой или все проверки не завершатся успешно.Как лидер по безопасности, обеспокоенный безопасностью развертывания кода, вы можете использовать проверки подписи кода Lambda для удовлетворения различных гарантий безопасности:

  • Целостность — Обеспечивает уверенность в том, что код не был изменен, гарантируя, что подпись на артефакте сборки криптографически действительна.
  • Несоответствие исходного кода — гарантирует, что только доверенные лица или разработчики могут развертывать код.
  • Истечение срока действия — Обеспечивает гарантию того, что код, работающий в вашей среде, не устарел, гарантируя, что подписи были созданы в течение определенной даты и времени.
  • Отзыв — позволяет администраторам безопасности удалять доверие, аннулируя подписи постфактум, чтобы их нельзя было использовать для развертывания кода, если они были раскрыты или им больше не доверяют.

Последние три проверки выполняются только в том случае, если вы установили политику проверки подписи — параметр UntrustedArtifactOnDeployment — в CSC на ENFORCE. Если для политики задано значение WARN, то при сбоях в любой из проверок несоответствия, истечения срока действия и отзыва в Amazon CloudWatch будет регистрироваться метрика, называемая ошибкой проверки подписи.Лучше всего для этого параметра изначально установить для политики значение WARN. Затем вы можете отслеживать предупреждения, если они есть, и обновлять политику для принудительного применения, когда вы уверены в выводах CloudWatch.

Централизованное принудительное подписание

В этом сценарии у вас есть группа администраторов безопасности, которая централизованно управляет и утверждает профили подписи. Команда централизует профили подписи, чтобы гарантировать, что весь код, работающий в Lambda, создан доверенным разработчиком и не подвергался подделке после подписания.Для этого команда администраторов безопасности хочет обеспечить, чтобы разработчики — в той же учетной записи — могли создавать функции Lambda только с профилями подписи, одобренными командой. Владея профилями подписи, используемыми группами разработчиков, группа безопасности контролирует жизненный цикл подписей и возможность отзывать подписи. Ниже приведены инструкции по созданию профиля подписи и CSC, а затем по обеспечению их использования.

Создать профиль подписывания

Чтобы создать профиль подписи, вы будете использовать интерфейс командной строки AWS (AWS CLI).Начните с входа в свою учетную запись в качестве центральной роли безопасности . Это административная роль с разрешениями, необходимыми для настройки подписывания кода. Вы создадите профиль подписи для приложения с именем ABC . Эти примеры команд написаны с предварительно заполненными значениями для таких вещей, как имена профилей, идентификаторы и описания. Измените их в соответствии с вашим приложением.

Чтобы создать профиль подписи
  1. Запустите эту команду:
      aws signer put-signing-profile --platform-id "AWSLambda-SHA384-ECDSA" --profile-name profile_for_application_ABC
      

    Выполнение этой команды даст вам версию профиля подписи ARN .Это будет выглядеть примерно так: arn:aws:signer:sa-east-1:XXXXXXXXXXXX:/signing-profiles/profile_for_application_ABC/XXXXXXXXXX. Запишите это значение для использования в последующих командах.

    Как администратор безопасности вы должны предоставить разработчикам доступ к использованию профиля для подписи. Вы делаете это с помощью команды add-profile-permission. Обратите внимание, что в этом примере вы явно предоставляете разрешение только для действия signer:StartSigningJob. Возможно, вы захотите предоставить разрешения другим действиям, таким как signer:GetSigningProfile или signer:RevokeSignature, выполнив дополнительные вызовы add-profile-permission.

  2. Запустите эту команду, заменив <имя-роли> на участника, который вы используете:
      разрешение на добавление профиля подписанта aws \
    --profile-name profile_for_application_ABC \
    --action signer:StartSigningJob \
    --principal  <имя-роли>  \
    --statement-id testStatementId
      

Создать CSC

Вы также хотите создать CSC с профилем подписи, который вы, как администратор безопасности, хотите, чтобы все ваши разработчики использовали.

Для создания CSC

Запустите эту команду, заменив выходными данными шага 1 предыдущей процедуры — Создать профиль подписи :

  aws lambda create-code-signing-config \
--description "Приложение ABC CSC" \
--allowed-publishers SigningProfileVersionArns=    \
--code-signing-policies "UntrustedArtifactOnDeployment"="Принудительно"
  

Выполнение этой команды даст вам CSCARN , который будет выглядеть примерно так: arn:aws:lambda:sa-east-1:XXXXXXXXXXXX:code-signing-config:approved-csc-XXXXXXXXXXXXXXXXXX.Запишите это значение, чтобы использовать его позже.

Напишите политику IAM, используя новый CSC

Теперь, когда команда администраторов безопасности создала этот CSC, как они могут гарантировать, что все разработчики будут его использовать? Администраторы могут использовать IAM для предоставления доступа к API CreateFunction, используя новый ключ условия lambda:CodeSigningConfig с созданным вами CSC ARN. Это гарантирует, что разработчики смогут создавать функции только при включенной подписи кода.

Эта политика IAM позволит ролям разработчиков создавать функции Lambda, но только в том случае, если они используют утвержденный CSC.Дополнительные пункты Запрещают разработчикам создавать свои собственные профили подписи или CSC, поэтому они вынуждены использовать те, что предоставляются центральной командой.

Чтобы написать политику IAM

Выполните следующую команду. Замените на ранее созданный CSC ARN.

  { "Версия": "2012-10-17", "Утверждение": [ { "Эффект": "Разрешить", "Действие": [ "лямбда:CreateFunction", "лямбда:PutFunctionCodeSigningConfig" ], "Ресурс" : "*", "Условие": { "ForAnyValue:StringEquals": { "лямбда:CodeSigningConfig": ["    "] } } }, { "Эффект": "Запретить" , "Действие": [ "signer:PutSigningProfile", "лямбда:DeleteFunctionCodeSigningConfig", "лямбда:UpdateCodeSigningConfig", "лямбда:DeleteCodeSigningConfig", "лямбда:CreateCodeSigningConfig" ], "Resource": "*" } ]
}
  

Создать подписанную лямбда-функцию

Теперь у разработчиков есть разрешение на создание новых функций Lambda, но только в том случае, если функции настроены с утвержденным CSC.Утвержденный CSC может указывать параметры политик подписи Lambda и точно перечислять, какие профили утверждены для подписи функционального кода. Это означает, что разработчики в этой учетной записи смогут создавать функции только в том случае, если функции подписаны с помощью профиля, утвержденного центральной командой, и разрешения разработчика были добавлены к используемому профилю подписи.

Чтобы создать лямбда-функцию со знаком
  1. Загрузите любой файл кода Lambda в корзину Amazon Simple Storage Service (Amazon S3) с именем main-function.молния. Обратите внимание, что для корзины S3 должна быть включена версия.
  2. Подпишите заархивированную функцию Lambda с помощью AWS Signer и следующей команды, заменив и правильными данными из загруженного файла main-function.zip.
      aws signer start-signing-job \ --source 's3={bucketName=   , version=   , key=main-function.zip}' \
    --destination 's3={bucketName=   , префикс=signed-}' \
    --profile-name profile_for_application_ABC
      
  3. Загрузите только что созданный ZIP-файл из корзины Lambda.Он будет называться примерно как signed-XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.zip.
  4. Для удобства переименуйте его в signed-main-function.zip.
  5. Выполните следующую команду, заменив на ARN вашей роли выполнения Lambda и заменив результатом предыдущей процедуры Create CSC .
      aws lambda create-function \ --function-name "signed-main-function" \ --runtime "python3.8" \ --role  <лямбда-роль>  \ --zip-file "fileb://signed-main-function.zip" \ --handler lambda_function.lambda_handler \ --code-signing-config-arn   
      

Централизация между счетами

Этот шаблон поддерживает вариант использования, когда администраторы безопасности и разработчики работают в одной учетной записи. Возможно, вы захотите реализовать это для разных учетных записей, что требует создания CSC в определенных учетных записях, где разработчикам необходимо развертывать и обновлять функции Lambda.Для этого можно использовать наборы стеков AWS CloudFormation для развертывания CSC. Наборы стеков позволяют развертывать стеки CloudFormation в нескольких учетных записях AWS. Использование наборов стеков AWS CloudFormation для нескольких учетных записей в организации AWS показывает, как использовать шаблон AWS CloudFormation для развертывания в нескольких учетных записях.

Администраторы безопасности могут обнаруживать и реагировать на любые изменения в наборе стека развернутых CSC, используя обнаружение дрейфа. Обнаружение дрейфа — это функция AWS CloudFormation, которая обнаруживает неуправляемые изменения в ресурсах, развернутых с помощью StackSets.Чтобы завершить решение, реализуйте автоматическое исправление смещения для AWS CloudFormation с помощью Amazon CloudWatch, и AWS Lambda предлагает решение для автоматического исправления при обнаружении смещения в стеке CloudFormation.

Межаккаунтовая проверка для слоев Lambda

На данный момент у вас есть инструменты для подписи вашего собственного кода Lambda, чтобы никто не мог его изменить, и вы рассмотрели шаблон, в котором одна команда создает и владеет профилями подписи, которые будут использоваться разными разработчиками.Давайте рассмотрим еще один расширенный шаблон, в котором вы публикуете код в виде подписанного слоя Lambda в одной учетной записи, а затем используете его в функции Lambda в отдельной учетной записи. Слой Lambda — это архив, содержащий дополнительный код, который вы можете включить в функцию.

Для этого давайте рассмотрим, как настроить подпись кода, когда вы используете слои в двух учетных записях. Слои позволяют использовать библиотеки в вашей функции без необходимости включать их в пакет развертывания. Также можно опубликовать слой в одной учетной записи, а другая учетная запись будет использовать этот слой.Давайте выступим в роли издателя слоя. В этом случае вы хотите использовать подпись кода, чтобы потребители вашего уровня могли быть уверены в безопасности, что никто не подделывал уровень. Обратите внимание, что если вы включите подписывание кода для проверки подписей на слое, Lambda также проверит подписи в коде функции. Поэтому все ваши артефакты развертывания должны быть подписаны с использованием профиля, указанного в CSC, прикрепленном к функции.

На рис. 3 показан шаблон уровня нескольких учетных записей, где вы подписываете слой в учетной записи публикации, а функция использует этот уровень в другой учетной записи-потребителе.

Рисунок 3. Этот расширенный шаблон поддерживает несколько слоев учетных записей

Вот шаги для создания этой установки. Вы будете входить в две разные учетные записи: учетную запись публикации и учетную запись потребления .

Создание профиля подписи издателя

Выполнение этой команды даст вам версию профиля ARN. Запишите значение, возвращенное для использования на более позднем этапе.

Создание профиля подписи издателя
  1. В интерфейсе командной строки AWS войдите в свою учетную запись публикации.
  2. Запустите эту команду, чтобы создать профиль подписывания для вашего издателя:
      aws signer put-signing-profile --platform-id "AWSLambda-SHA384-ECDSA" --profile-name publisher_approved_profile1
      

Подпишите свой код слоя, используя профиль подписи

Затем вы хотите подписать код слоя с помощью этого профиля подписи. В этом примере используйте код пустого слоя из этого проекта GitHub. Вы можете создать свой собственный слой, создав ZIP-файл со всеми вашими файлами кода, включенными в каталог, поддерживаемый вашей средой выполнения Lambda.Слои AWS Lambda содержат инструкции по созданию собственного слоя.

Затем вы можете подписать код слоя, используя профиль подписи.

Чтобы подписать код слоя
  1. Назовите файл кода слоя Lambda Blank-python.zip и загрузите его в корзину S3.
  2. Подпишите заархивированную функцию Lambda с помощью AWS Signer с помощью следующей команды. Замените и данными из загруженного пустого файла python.молния.
      aws signer start-signing-job \ --source 's3={bucketName=   , version=   , key=blank-python.zip}' \
    --destination 's3={bucketName=   , префикс=signed-}' \
    --profile-name publisher_approved_profile1
      

Опубликуйте свой подписанный слой

Теперь опубликуйте получившийся подписанный слой. Обратите внимание, что сами слои не имеют проверки подписи при развертывании.Однако подписи будут проверены, когда они будут добавлены в функцию.

Чтобы опубликовать подписанный слой
  1. Загрузите новый подписанный ZIP-файл из корзины S3 и переименуйте его в signed-layer.zip.
  2. Запустите следующую команду, чтобы опубликовать свой слой:
      версия публикации уровня aws lambda \
    --layer-name lambda_signing \
    --zip-файл "fileb://signed-layer.zip" \
    --совместимые среды выполнения python3.8 python3.7  

Эта команда вернет информацию о недавно опубликованном слое.Найдите LayerVersionArn и запишите его для использования позже.

Предоставить доступ для чтения

На последнем шаге в учетной записи издателя вы должны предоставить доступ для чтения к слою с помощью команды add-layer-version-permission. В следующей команде вы предоставляете доступ к отдельной учетной записи, используя основной параметр.

(необязательно) Вместо этого вы можете предоставить доступ ко всем учетным записям в вашей организации, используя «*» в качестве принципала и добавив параметр идентификатора организации.

Чтобы предоставить доступ для чтения
  • Выполните следующую команду, чтобы предоставить доступ для чтения к вашему слою, заменив <идентификатор потребляющей учетной записи> на идентификатор вашей второй учетной записи :
      aws lambda add-layer-version-permission \
    --layer-name lambda_signing \
    --версия-номер 1 \
    --statement-id для потребляющей учетной записи \
    --action lambda:GetLayerVersion \
    --principal  <идентификатор потребляющей учетной записи>   

Создать CSC

Пришло время переключить интерфейс командной строки AWS для работы с потребляющей учетной записью .Эта потребляющая учетная запись может создать CSC для своих функций Lambda, который указывает, какие профили подписи разрешены.

Для создания CSC
  1. В интерфейсе командной строки AWS выйдите из своей учетной записи публикации и войдите в учетную запись пользователя.
  2. Использующей учетной записи потребуется собственный профиль подписи для подписи основного лямбда-кода. Выполните следующую команду, чтобы создать его:
      aws signer put-signing-profile --platform-id "AWSLambda-SHA384-ECDSA" --profile-name Consumer_approved_profile1
      
  3. Выполните следующую команду, чтобы создать CSC, который позволяет подписывать код либо издателем, либо потребителем.Замените версией профиля ARN, созданной на предыдущем шаге. Замените профилем подписи из процедуры Создание профиля подписи издателя . Запишите CSC, возвращенный этой командой, чтобы использовать его в последующих шагах.
      aws lambda create-code-signing-config \
    --description "Разрешить слои от издателя" \
    --allowed-publishers SigningProfileVersionArns="    ,    " \
    --code-signing-policies "UntrustedArtifactOnDeployment"="Принудительно"
      

Создание лямбда-функции с помощью CSC

При создании функции, использующей подписанный слой, вы можете передать созданный вами CSC.На этом шаге Lambda проверит подпись кода функции.

Чтобы создать лямбда-функцию
  1. Используйте собственную функцию лямбда-кода или сделайте копию пустого файла python.zip и переименуйте его в Consumer-main-function.zip.) Загрузите файл Consumer-main-function.zip в корзину S3 с версией версии в своей учетной записи пользователя.

    Примечание . Если для корзины S3 не включено управление версиями, процедура завершится ошибкой.

  2. Подпишите функцию с помощью профиля подписи учетной записи потребителя.Замените и в следующей команде именем корзины S3, в которую вы загрузили Consumer-main-function.zip, и версией.
      aws signer start-signing-job \ --source 's3={bucketName=    , version=    , key=consumer-main-function.zip}' \
    --destination 's3={bucketName=   , префикс=signed-}' \
    --profile-name Consumer_approved_profile1
      
  3. Загрузите новый файл и переименуйте его в подписанную-потребительскую-основную-функцию.молния.
  4. . Выполните следующую команду, чтобы создать новую функцию Lambda, заменив <лямбда-роль> действительной ролью выполнения лямбда и значением, возвращенным из предыдущей процедуры: Создание CSC .
      aws lambda create-function \ --function-name "signed-consumer-main-function" \ --runtime "python3.8" \ --role  <лямбда-роль>  \ --zip-file "fileb ://подписанная-потребительская-основная-функция.zip" \ --handler lambda_function.lambda_handler \ --code-signing-config   
      
  5. Наконец, добавьте подписанный слой из учетной записи публикации в конфигурацию этой функции. Выполните следующую команду, заменив результатом предыдущего шага . Опубликуйте подписанный слой .
      aws lambda update-function-configuration \
    --function-name "подписанная-потребительская-основная-функция" \
    --layers "    "  

На этом шаге Lambda проверит подпись кода слоя.Если сигнатура любого развернутого артефакта слоя повреждена, функция Lambda остановит вас от присоединения слоя и развертывания вашего кода. Это верно независимо от того, какой режим вы выберете — ПРЕДУПРЕЖДЕНИЕ или ПРИНУДИТЕЛЬНЫЙ. Если у вас есть несколько слоев для добавления к вашей функции, вы должны подписать все слои, вызываемые в функции Lambda.

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

Заключение

Вы узнали о некоторых передовых методах и шаблонах использования подписи кода для AWS Lambda. Вы знаете, как подписывание кода вписывается в безопасный SDLC, и какую ценность вы получаете от каждой из проверок подписывания кода. Вы также изучили два шаблона использования подписи кода для распределенного владения — один для централизованного подписания и один для проверки на уровне нескольких учетных записей.Независимо от вашей роли — разработчика, центральной группы безопасности или издателя уровня — вы можете использовать эти инструменты для обеспечения целостности артефактов кода в вашей организации.

Дополнительные сведения о подписи кода Lambda см. в разделе Настройка подписи кода для AWS Lambda.

Если у вас есть отзывы об этом сообщении, отправьте комментарии в разделе комментариев ниже. Если у вас есть вопросы по этому сообщению, начните новую тему на форуме AWS Lambda или обратитесь в службу поддержки AWS.

Хотите больше инструкций по AWS Security, новостей и анонсов функций? Следуйте за нами на Twitter.

Кассия Мартин

Кассия — архитектор систем безопасности из Нью-Йорка. Она работает с крупными финансовыми учреждениями, решая проблемы архитектуры безопасности и обучая их облачным инструментам и шаблонам. Кассия работает в сфере безопасности более 10 лет и имеет большой опыт в области безопасности приложений.

Что нужно знать о варианте лямбда

По словам эпидемиолога Калифорнийского университета в Беркли, новый вариант уже появился на горизонте и готов стать доминирующим штаммом во всем мире.

Вариант лямбда начал циркулировать в Перу в августе 2020 года. Первый задокументированный образец варианта появился в декабре того же года. Теперь он распространился из Латинской Америки в Соединенные Штаты и за их пределы, что привело к тому, что Всемирная организация здравоохранения охарактеризовала его как вариант, представляющий интерес.

По состоянию на конец июля в Калифорнии было зарегистрировано 144 случая лямбда-варианта, что очень мало для штата с населением более 39 миллионов человек, согласно данным, полученным San Francisco Chronicle (SFGATE и San Francisco Chronicle). оба принадлежат Hearst, но работают независимо друг от друга).

По данным базы данных GISAID, в США зарегистрировано более 1000 случаев лямбда-варианта, и более 4000 задокументированных случаев по всему миру.

Остается вопрос: насколько нас должен волновать этот вариант?

Феньонг Лю, эпидемиолог из Калифорнийского университета в Беркли, подчеркнул, что «мы должны быть очень, очень обеспокоены».

«Я чувствую, что нам действительно нужно обратить на это внимание, потому что этот вариант циркулирует с 2020 года, в основном ограничен Южной Америкой, но теперь он становится глобальным», — сказал Лю.

Лю процитировал некоторые предварительные исследования, которые показывают, что вариант может быть более устойчивым к вакцине по сравнению с более ранними вариантами, такими как варианты альфа, бета и дельта. Он добавил, что вакцины по-прежнему очень эффективны. Это может быть похоже на дельта-вариант, при котором у вакцинированных людей при заражении обычно развиваются легкие симптомы или их отсутствие.

Это имеет смысл с точки зрения общественного здравоохранения, поскольку вариант циркулирует по крайней мере с конца 2020 года, что означает, что он «адаптировался к человеческой популяции до такой степени, что может иметь преимущество с точки зрения передачи, поэтому он будет стать глобальным штаммом», — сказал Лю.

Вакцины, как указал Лю, были разработаны с учетом более ранних штаммов.

В то же время Лю подчеркнул, что «мы очень мало знаем о варианте лямбда с точки зрения его передачи и вирулентности». Многое еще предстоит увидеть.

Он ожидает, что вариант будет циркулировать так же, как дельта-вариант, который вызывает новый всплеск коронавируса в США 

«Я думаю, что лямбда-вариант может делать то же самое, что и дельта-вариант, — сказал Лю.

Он считает, что дельта-вариант не будет большой проблемой через два-три месяца, так как у людей выработается естественный иммунитет.

«Мы просто не знаем, будет ли дальше развиваться лямбда или что-то еще», — сказал он.

Лю подчеркнул, что для того, чтобы остановить COVID-19, мы должны в первую очередь остановить цикл возникающих вариантов и стремиться к тому, чтобы во всем мире было вакцинировано больше людей.

Author:

Добавить комментарий

Ваш адрес email не будет опубликован.