2009-07-13 36 views
125

Điều này có thể là ngớ ngẩn, nhưng nó được nagging phía sau não của tôi trong một thời gian.Điều nào tốt hơn trong python, del hoặc delattr?

Python cho chúng ta hai được xây dựng theo nhiều cách để xóa thuộc tính từ các đối tượng, các del từ lệnh và delattr tích hợp chức năng. Tôi thích delattr vì nó Tôi nghĩ một chút của nó rõ ràng hơn:

del foo.bar 
delattr(foo, "bar") 

Nhưng tôi tự hỏi, nếu có thể có dưới-the-hood khác biệt giữa chúng.

Trả lời

201

Cách thứ nhất hiệu quả hơn số thứ hai. del foo.bar biên dịch để hai hướng dẫn bytecode:

2   0 LOAD_FAST    0 (foo) 
       3 DELETE_ATTR    0 (bar) 

trong khi delattr(foo, "bar") mất năm:

2   0 LOAD_GLOBAL    0 (delattr) 
       3 LOAD_FAST    0 (foo) 
       6 LOAD_CONST    1 ('bar') 
       9 CALL_FUNCTION   2 
      12 POP_TOP    

này chuyển thành các hoạt động đầu tiên hơi nhanh hơn (nhưng nó không phải là một sự khác biệt lớn - .15 ms trên máy tính của tôi).

Giống như những người khác đã nói, bạn thực sự chỉ nên sử dụng biểu mẫu thứ hai khi thuộc tính bạn đang xóa được xác định động.

[Edited để hiển thị các hướng dẫn bytecode tạo ra bên trong một hàm, nơi trình biên dịch có thể sử dụng LOAD_FASTLOAD_GLOBAL]

+4

Bạn đã sử dụng công cụ nào để tạo ra công cụ này? – Triptych

+25

Mô-đun 'dis'. Bạn có thể chạy nó từ dòng lệnh bằng cách sử dụng 'python -m dis' và gõ một số mã, hoặc tách một hàm bằng' dis.dis() '. – Miles

+14

Tối ưu hóa sớm là gốc rễ của mọi điều ác. ;-) Nhưng có, bạn là đúng, tất nhiên. –

14

Đó thực sự là vấn đề ưu tiên, nhưng điều đầu tiên có lẽ là thích hợp hơn. Tôi sẽ chỉ sử dụng thứ hai nếu bạn không biết tên của thuộc tính mà bạn đang xóa trước thời hạn.

16

Không thể nghi ngờ trước đây. Theo quan điểm của tôi, điều này giống như hỏi xem foo.bar có tốt hơn getattr(foo, "bar") không và tôi không nghĩ rằng có ai đó đang đặt câu hỏi đó :)

+3

Tôi chắc chắn có ít nhất * một * người ở đó muốn sử dụng getattr (foo, "bar") trên foo.bar. Cấp, tôi sẽ không đồng ý với họ. Nhưng một người vẫn đủ để làm cho nó không thể nghi ngờ gì trước đây. –

+2

@ Jason Sau đó, không có gì là "không nghi ngờ gì tốt hơn" hơn bất cứ điều gì khác bằng cách giải thích của bạn của cụm từ. Tôi nghĩ rằng đây là một cách sử dụng hoàn toàn hợp lý "không nghi ngờ gì". – Phob

+21

getattr là thích hợp hơn khi có khả năng là thuộc tính không tồn tại và bạn muốn đặt giá trị mặc định mà không cần phải viết try/except blocks. tức là. gettattr (foo, "bar", None) –

0

Nếu bạn nghĩ rằng delattr là rõ ràng hơn, thì tại sao không sử dụng getattr tất cả các thời gian chứ không phải object.attr?

Đối với dưới mui xe ... đoán của bạn là tốt như tôi. Nếu không tốt hơn đáng kể.

5

Cũng giống như getattr và setattr, delattr chỉ nên được sử dụng khi tên thuộc tính không xác định.

Trong ý nghĩa đó, nó tương đương với một số tính năng python được sử dụng để truy cập vào các chức năng tích hợp ở mức độ thấp hơn so với bình thường đã có sẵn, chẳng hạn như __import__ thay vì importoperator.add thay vì +

3

Không chắc chắn về các hoạt động bên trong, nhưng từ một khả năng tái sử dụng mã và không phải là một quan điểm đồng nghiệp jerk, sử dụng del. Nó rõ ràng hơn và được hiểu bởi những người đến từ các ngôn ngữ khác nữa.

25
  • del rõ ràng và hiệu quả hơn;
  • delattr cho phép xóa thuộc tính động.

Hãy xem xét các ví dụ sau:

for name in ATTRIBUTES: 
    delattr(obj, name) 

hay:

def _cleanup(self, name): 
    """Do cleanup for an attribute""" 
    value = getattr(self, name) 
    self._pre_cleanup(name, value) 
    delattr(self, name) 
    self._post_cleanup(name, value) 

Bạn không thể làm điều đó với del.

+0

Bạn có thể làm điều thứ hai với del. 'del self .__ dict __ [name]', giả sử tất nhiên không có chuyện kinh doanh vui nhộn xảy ra với lớp meta – smac89

1

Đó là một câu hỏi cũ, nhưng tôi muốn đặt 2 cent của tôi trong.

Mặc dù, del foo.bar là tao nhã hơn, thỉnh thoảng bạn sẽ cần delattr(foo, "bar"). Giả sử, nếu bạn có giao diện dòng lệnh tương tác cho phép người dùng tự động xóa bất kỳ thành viên nào trong đối tượng bằng cách nhập tên, thì bạn không còn cách nào khác ngoài việc sử dụng biểu mẫu sau.

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