2015-02-10 2 views
5

Может ли кто-нибудь объяснить это поведение лямбда-функций?Лямбда и несколько операторов в Python

import sys 
X = lambda: sys.stdout.write('first');sys.stdout.write("second") 
X() 

Возвращает: -> secondfirst

И еще одна проблема:

lambda: sys.stdout.write("...");sys.exit(0) 

Или

lambda: sys.exit(0);sys.stdout.write("...") 

Не выполняет правильно. И еще один вопрос, почему в первом потоке выполнения праймера идет справа налево?

Попытка с: Python3 + (3.4, 3.2) ОС: Linux (Ubuntu), OSX

+0

Почему вы хотите сделать лямбду таким вот? –

+0

Я не хочу использовать лямбда таким образом, первый праймер был найден в коде плагина nagios, и я был любопытным, почему он работает таким образом :) – user4549992

+0

'lambda's are * expressions * и их тело должно быть выражением. Вы не можете ** поставить утверждение внутри лямбды, не говоря уже о нескольких утверждениях. – Bakuriu

ответ

3

Есть два заявления на на линии, первый находится в lambda, что только получает called после sys.stdout.write("second") уже бежать , X() называет лямбду.

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

Doing эквивалент с нормальной функцией:

sys.stdout.write("second") 
def x(): 
    sys.stdout.write('first') 

x()  

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

x= lambda: sys.exit(0);sys.stdout.write("...") 
x() 

Использование ; и имеющий несколько операторов на одном линия не является пифонической или вообще очень хорошей идеей.

+0

2 команды в одной строке меня смутили. Я думал, что они все в теле лямбды. – user4549992

+0

@ user4549992, вот почему ';' на самом деле не очень хорошая идея. Несколько заявлений не являются питоническими, и, как вы выяснили, это может ввести в заблуждение –

+0

Да: (спасибо за ответ. – user4549992

2

Первый код переводится:

import sys 
X = lambda: sys.stdout.write('first') 
sys.stdout.write("second") 
X() 

Как вы можете видеть, что теперь ясно second работает до того first.

9

sys.stdout.write ("second") не является частью лямбда.

«second» всегда печатается, даже если вы не вызываете X. Другими словами, вызов X только печатает «первым».

Ваш код может быть переписан как;

import sys 
X = lambda: sys.stdout.write('first') 
sys.stdout.write("second") 
print X() 

Если вы хотите, чтобы два утверждения, выполненные лямбдой, помещали их в кортеж;

lambda: (sys.stdout.write('first'),sys.stdout.write("second")) 
3

Синтаксис для lambda является:

lambda <args>: <expression> 

, где <expression> должен быть единым выражением. Это не может быть оператор или несколько операторов или несколько выражений, разделенных ;.

Что происходит в вашем коде, что lambda имеет более высокий приоритет по сравнению с ;, так что получает синтаксический анализ: X = lambda: sys.stdout.write('first') с последующим sys.stdout.write("second"). Добавление скобок вокруг sys.stdout.write('first') ; sys.stdout.write("second") не будет работать и приведет к синтаксической ошибке.

Мой трюк, чтобы сделать несколько вещей внутри лямбда:

f = lambda: [None, sys.stdout.write('first'), sys.stdout.write("second")][0] 

, а другой:

f = lambda: [None, sys.stdout.write("..."), sys.exit(0)][0] 

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

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

Смежные вопросы