2012-04-28 26 views
8

Tôi đang cố gắng tạo một hàm để xóa một hàm khác.Xóa chức năng

def delete_function(func): 
    del func 

là những gì tôi có cho đến nay, nhưng vì lý do nào đó nó không hoạt động.

def foo(): 
    print("foo") 
delete_function(foo) 

dường như không thực hiện điều này. Tôi biết người ta có thể làm điều đó dễ dàng, chỉ cần

del(foo) 

nhưng tôi đang cố gắng làm điều đó theo một cách khác. Làm sao?

+5

vấn đề bạn hy vọng sẽ giải quyết với kỹ thuật này là gì? – SingleNegationElimination

+1

Thật vậy. Tại sao, vì tình yêu của mã, tại sao? – Macke

+0

Nếu bạn phải làm điều này, có thể có điều gì đó sai với việc triển khai của bạn. –

Trả lời

13

Xóa một chức năng không thực sự là một cái gì đó bạn làm cho bản thân chức năng; đó là điều bạn làm cho không gian tên mà nó tồn tại. (Chỉ cần xóa số 3 khỏi danh sách không phải là thứ bạn làm với số 3, đó là điều bạn làm trong danh sách.)

Giả sử bạn nói

def foo(x): return 1 
bar = foo 

Sau đó (nhiều hơn hoặc ít hơn) bạn có hai tên, foobar, với cùng chức năng chính xác. Bây giờ giả sử bạn gọi delete_function(foo) hoặc delete_function(bar). cùng một điều chính xác, cụ thể là đối tượng hàm, đang được chuyển đến delete_function.Nhưng những gì bạn thực sự muốn xóa là liên kết giữa tên foo hoặc bar và đối tượng đó - và không có cách nào có thể delete_function (tuy nhiên bạn xác định nó) có thể biết liệu đó là foo hoặc bar hoặc thứ gì đó khác mà bạn muốn loại bỏ của.

(Ừm ... Thực ra thì có. Có những điều khó chịu mà bạn có thể làm để cho mã trong số delete_function biết thêm về cách gọi nó. Nhưng thậm chí không nghĩ đến suy nghĩ về chúng.)

So. Các tùy chọn của bạn như sau. (1) Những điều khó hiểu, như đã đề cập. Đừng. (2) Vượt qua delete_function không phải là đối tượng chức năng nhưng thông tin về tên của hàm và thứ mà bạn đang cố xóa nó. Điều này là xấu xí và vô ích. (3) Đừng bận tâm.

Tôi khuyên bạn nên # 3, trừ khi lý do duy nhất bạn làm điều này là tìm hiểu thêm về cách Python hoạt động. Trong trường hợp thứ hai, một nơi tốt để bắt đầu có thể là http://docs.python.org/reference/executionmodel.html.

4

Nó sẽ không hoạt động.

Điều bạn đang cố gắng làm là, về cơ bản, không gian tên của người gọi.

Hãy thử điều này:

print "0", locals() 
def foo(): pass 
print "1", locals() 
del foo 
print "2", locals() 

Lưu ý rằng

  1. người dân địa phương dict tại 0 và 2 giống hệt nhau, và lúc 1 gần - ngoại trừ nó có nhiệm vụ bổ sung của foo.
  2. del là một tuyên bố và không phải là một chức năng

Nếu bạn làm del trong một chức năng delete_function(), về cơ bản các nhiệm vụ trong phạm vi chức năng của bạn sẽ được xóa (đó là không hiệu quả bởi vì hàm được chấm dứt ngay lập tức), trong khi người gọi giữ nhiệm vụ.

Nói chính xác, del không xóa đối tượng, mà chỉ đơn thuần chỉ định từ tên đến đối tượng. Các đối tượng bị xóa "tự động" (rác được thu thập) ngay sau khi chúng không được tham chiếu nữa.

COULD hoạt động những gì bạn cố gắng thực hiện bằng cách kiểm tra khung ngăn xếp và chuyển tên sẽ bị xóa dưới dạng chuỗi, nhưng nó sẽ là PITA.

Có lẽ bạn thử

del locals()['foo'] 

hoặc

locals()['foo'] = 42 

? Nhưng tôi nghĩ rằng nó không phải là guarantteed rằng nó thực sự sửa đổi từ điển địa phương thực sự, nó cũng có thể hoạt động trên một bản sao và do đó ở lại effectless ...

7

Kể từ foo là một toàn cầu, bạn có thể xóa nó khỏi định nghĩa toàn cầu:

def delete_func(func): 
    del globals()[func.func_name] 
+0

+1 Đây là giải pháp đơn giản nhất. –

+5

Quá tệ nếu định nghĩa của 'func' mà bạn đang cố xoá thực ra không nằm trong không gian tên chung. (Ví dụ, bởi vì nó bên trong một chức năng khác.) –

+0

@GarethMcCaughan Vâng, giải pháp này chỉ tốt cho các chức năng toàn cầu (nhưng tôi nghĩ câu trả lời của tôi làm cho nó khá rõ ràng). –

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