2010-05-24 5 views
5

tôi nhận thấy một vấn đề khi tôi đã cố gắng sử dụng del trong một lambda mỏng ra một danh sách các chủ đề để chỉ những người chạy:Python del() được xây dựng trong không thể được sử dụng trong nhiệm vụ?

map(lambda x: del(x) if not x.isAlive() else x, self.threads) 

Bỏ qua trong một giây rằng điều này không làm bất cứ điều gì, tôi chỉ lừa xung quanh với bản đồ, giảm và lambda.

Điều này không thành công với lỗi cú pháp tại del (x). Với một số rối tung xung quanh, tôi nghĩ rằng vấn đề là del() không trả về một giá trị. Ví dụ, điều này không thành công với các lỗi tương tự:

b = 5 
x = del(b) 

này không, tuy nhiên:

def rmThis(x): del(x) 

Có nghĩa là tôi đang sử dụng workaround này:

map(lambda x: rmThis(x) if not x.isAlive() else x, self.threads) 

Vậy là hạn chế chỉ vì del() không trả về một giá trị? Tại sao không?

Tôi đang sử dụng python 2.6.2

+0

Có cần phải gọi 'del' trên đối tượng chuỗi một cách rõ ràng không? Nếu bạn có thể để nó tới bộ đếm tham chiếu hoặc bộ thu gom rác, bạn có thể viết tihs: '[thread for thread in self.threads if thread.isAlive()]'. –

+3

Ngay cả khi điều này làm việc, nó sẽ không hoạt động :) Bạn không thể xóa các yếu tố từ một iterable trong khi bạn đang iterating trên nó. –

Trả lời

9

Hai vấn đề. Người đầu tiên tinh tế hơn nên tôi sẽ giải thích điều đó trước tiên.

Vấn đề là xóa bỏ ràng buộc biến. Vượt qua nó một giá trị sẽ không phục vụ mục đích của bạn.

Dưới đây là một minh hoạ

>>> a = 5 
>>> del(a) 
>>> a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'a' is not defined 
>>> def mydel(x): del(x) 
... 
>>> a = 5 
>>> mydel(a) 
>>> a 
5 
>>> 

Như bạn có thể nhìn thấy. Trong trường hợp đầu tiên, biến số a đã bị xóa khỏi không gian tên hiện tại. Không có cách nào để chỉ đến đối tượng mà nó chỉ ra nữa (giả sử không có gì khác trỏ đến cùng một thứ).

Trong trường hợp thứ hai, bạn không xóa a khỏi không gian tên. Bạn đang xóa các ràng buộc của x trong không gian tên chức năng tác dụng của nó là bạn sẽ không thể sử dụng x như là một rvalue nữa trong chức năng (tức là nó là một biến không xác định).

Vấn đề thứ hai là SyntaxError đơn giản hơn. Các hàm Python lambda chỉ có thể có các biểu thức trong chúng chứ không phải các câu lệnh. del không phải là một biểu thức (tức là, không phải là một cuộc gọi chức năng) - đó là một tuyên bố (del_stmt) và do đó, nó không thể xuất hiện trong cơ thể của lambda. Bạn sẽ thấy cùng một vấn đề nếu bạn thử đặt print trong phần thân của lambda.

>>> lambda x: print x 
    File "<stdin>", line 1 
    lambda x: print x 
       ^
SyntaxError: invalid syntax 

Điều này cũng giải thích tại sao x=del(a) không thành công. Cú pháp câu lệnh không hợp lệ. Nó không phải là một chức năng có thể được gọi.

9

Hạn chế là del is a statement và không phải là một biểu hiện . Nó không "trả về một giá trị" vì các câu lệnh không trả về các giá trị trong Python.

Dạng lambda chỉ cho phép bạn đề cập đến biểu thức (vì có một tiềm ẩn return trước khi biểu thức), trong khi hình thức def cho phép một hàm tuyên bố duy nhất để được xác định trên cùng một dòng (như bạn đã làm với rmThis).

thường del được sử dụng mà không cần dấu ngoặc đơn, như:

del x 

Tuy nhiên, bao gồm ngoặc xung quanh tranh cãi như del(x) được cho phép nhưng không có nghĩa đó là một lời gọi hàm.

+1

Liên kết đó là những gì tôi cần, cảm ơn. – emcee

+0

+1 cho liên kết. –