2015-02-10 20 views
5

Có ai có thể giải thích rằng hành vi của các hàm lambda không?Lambda và nhiều câu lệnh trong Python

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

Returns: -> secondfirst

Và thêm một vấn đề:

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

Hoặc

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

Không thực hiện một cách chính xác. Và một câu hỏi nữa, tại sao trong dòng đầu tiên thực thi mồi đi từ phải sang trái?

Cố gắng với: Python3 + (3.4, 3.2) Hệ điều hành: Linux (Ubuntu), OSX

+0

Tại sao bạn muốn tạo một lambda như thế này? –

+0

Tôi không muốn sử dụng lambda theo cách đó, mồi đầu tiên được tìm thấy trong mã nagios plugin, và tôi là curios về lý do tại sao nó hoạt động theo cách đó :) – user4549992

+0

'lambda' s * biểu thức * và cơ thể của chúng phải là một biểu thức. Bạn ** không thể ** đặt một câu lệnh bên trong một lambda, hãy để một mình nhiều câu lệnh. – Bakuriu

Trả lời

3

Có hai phát biểu trên trên đường dây, đầu tiên là trong một lambda mà chỉ được called sau sys.stdout.write("second") có đã chạy . X() gọi lambda.

Vì vậy, nó không đi từ phải sang trái, chúng tôi chỉ có một lambda chỉ được gọi trên dòng tiếp theo. Nó không khác gì để định nghĩa một hàm, ghi vào sys.stdout và sau đó gọi hàm đó.

Làm tương đương với một chức năng bình thường:

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

x()  

Ví dụ khác của bạn, bạn cần phải gán các lambda và sau đó gọi nó là:

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

Sử dụng một ; và có nhiều báo cáo về một dòng không phải là pythonic hoặc một ý tưởng rất tốt nói chung.

+0

2 lệnh trong một dòng nhầm lẫn tôi. Tôi nghĩ tất cả họ đều ở trong cơ thể của lambda. – user4549992

+0

@ user4549992, đó là lý do tại sao ';' không thực sự là một ý tưởng hay. Nhiều tuyên bố không phải là pythonic và như bạn đã phát hiện ra có thể gây nhầm lẫn –

+0

Vâng: (thanx rất nhiều cho câu trả lời. – user4549992

2

mã đầu tiên chuyển đến:

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

Như bạn thấy, nó bây giờ rõ ràng second chạy trước first.

9

sys.stdout.write ("thứ hai") không phải là một phần của lambda.

'giây' luôn được in ngay cả khi bạn không gọi X. Nói cách khác gọi X chỉ in 'đầu tiên'.

Mã của bạn có thể được viết lại thành;

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

Nếu bạn muốn hai câu lệnh được thực hiện bởi lambda đặt chúng trong bộ;

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

Cú pháp cho lambda là:

lambda <args>: <expression> 

nơi <expression> phải là một biểu hiện duy nhất. Nó không thể là một câu lệnh hoặc nhiều câu lệnh hoặc nhiều biểu thức được phân cách bằng ;.

gì sẽ xảy ra trong mã của bạn là lambda có ưu tiên cao hơn so với ;, do đó được phân tích cú pháp như sau: X = lambda: sys.stdout.write('first') tiếp theo sys.stdout.write("second"). Việc thêm dấu ngoặc đơn vào khoảng sys.stdout.write('first') ; sys.stdout.write("second") sẽ không hoạt động và tạo ra lỗi cú pháp.

lừa tôi để làm nhiều thứ bên trong một lambda là:

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

và một trong những khác:

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

Tuy nhiên rằng loại đánh bại mục đích của một hàm lambda, mà là để làm một cái gì đó ngắn và thực sự đơn giản.

Tôi đoán điều đó sẽ vẫn ổn trong ví dụ cụ thể của bạn, nhưng trông giống như một hack.

Các vấn đề liên quan