2013-07-02 33 views
15

Tôi có một lớp mô hình django duy trì trạng thái là một thuộc tính đơn giản. Tôi đã thêm một số thuộc tính trợ giúp cho lớp để truy cập các trạng thái tổng hợp - ví dụ: is_live trả về false nếu trạng thái là bất kỳ một trong số ['closed', 'expired', 'deleted'] v.v.python Idiomatic - tài sản hoặc phương pháp?

Kết quả là mô hình của tôi có tập hợp các thuộc tính is_, thực hiện tra cứu rất đơn giản trên các đặc tính bên trong của đối tượng.

Bây giờ tôi muốn thêm thuộc tính mới, is_complete - ngữ nghĩa giống như tất cả các thuộc tính khác - kiểm tra boolean về trạng thái của đối tượng - tuy nhiên, kiểm tra này liên quan đến việc tải phụ thuộc (một-nhiều)) các đối tượng con, kiểm tra trạng thái của chúng và báo cáo lại dựa trên các kết quả - tức là thuộc tính này thực sự thực hiện một số truy vấn cơ sở dữ liệu (nhiều hơn một) và xử lý các kết quả.

Vì vậy, nó vẫn còn hợp lệ để mô hình như một tài sản (sử dụng trang trí @property trang trí), hay tôi thay vì bỏ qua trang trí và để nó như một phương pháp?

Việc sử dụng thuộc tính là phù hợp ngữ nghĩa với tất cả các thuộc tính khác is_. Sử dụng một phương pháp là nó chỉ ra cho các nhà phát triển khác rằng đây là một cái gì đó có triển khai phức tạp hơn, và do đó nên được sử dụng một cách tiết kiệm (tức là không phải bên trong vòng lặp for..).

from django.db import models 

class MyModel(models.Model): 

    state = CharField(default='new') 

    @property 
    def is_open(self): 
     # this is a simple lookup, so makes sense as a property 
     return self.state in ['new', 'open', 'sent'] 

    def is_complete(self): 
     # this is a complex database activity, but semantically correct 
     related_objects = self.do_complicated_database_lookup() 
     return len(related_objects)==0 

EDIT: Tôi đến từ một nền tảng .NET ban đầu, nơi sự phân cách đáng ngưỡng mộ xác định bởi Jeff Atwood như

"nếu có bất kỳ cơ hội ở tất cả các mã có thể đẻ trứng một đồng hồ cát, nó chắc chắn nên là một phương pháp. "

EDIT 2: nhẹ bản cập nhật cho câu hỏi - nó sẽ là một vấn đề để có nó như một phương pháp, gọi là is_complete, để có được tài sản và phương pháp trộn lẫn với tên tương tự - hoặc là chỉ khó hiểu?

Vì vậy - nó sẽ giống như thế này:

>>> m = MyModel() 
>>> m.is_live 
True 
>>> m.is_complete() 
False 
+0

Tôi nghĩ nó vẫn hợp lý. Bạn có thể lưu trữ kết quả dưới dạng 'self._is_complete' hoặc được tính toán nhiều lần không? Bạn có thể chạy tính toán ở chế độ nền hay tính toán chỉ hợp lệ khi thuộc tính được đánh giá? –

+0

@JaceBrowning: Tôi đã có chính xác ý tưởng tương tự (vui lòng xem câu trả lời của tôi). Tôi cho rằng điều này là không sao (nếu không, nó luôn luôn có thể được xóa). – Tadeck

+0

@Tadeck: không phải lo lắng. Tôi không biết đủ về 'django' để biết ứng dụng này có hợp lý hay không. –

Trả lời

9

Nó không quan trọng để làm điều đó, đặc biệt là nếu bạn sẽ sử dụng mẫu sau:

class SomeClass(models.Model): 
    @property 
    def is_complete(self): 
     if not hasattr(self, '_is_complete'): 
      related_objects = self.do_complicated_database_lookup() 
      self._is_complete = len(related_objects) == 0 
     return self._is_complete 

Chỉ cần nhớ rằng nó là "lưu trữ" kết quả, vì vậy việc thực hiện đầu tiên sẽ tính toán, nhưng sau đó sử dụng các kết quả hiện có.

+0

Cảm ơn @tadeck - Tôi nghĩ rằng đây là một cách tiếp cận hợp lệ, nhưng trên những gì tôi nên hỏi là liệu có các thuộc tính và phương thức hỗn hợp (với cùng quy ước đặt tên - xem câu hỏi chỉnh sửa 2)? –

+0

@ HugoRodger-Brown: Pep8 đề cập rằng cả hai phương pháp và cá thể biến chúng ta 'underscore_seperate_names', do đó, có nó hoàn toàn tốt đẹp. Khi cả phương thức và biến trả về một boolean, 'is_' là những gì tôi mong đợi tiền tố là tốt. – TyrantWave

+0

@TyrantWave: Tôi thường đồng ý. Thêm vào đó, các IDE tốt (hoặc trung bình) có thể cho biết khi nào một cái gì đó là một thuộc tính, một phương thức hay một thuộc tính nào đó khác, và hiển thị nó đúng cách. Ngoài ra, người ta có thể mong đợi các phương thức 'check_' hoặc không trả về bất kỳ thứ gì (về mặt kỹ thuật:' None'), hoặc chấp nhận một cuộc gọi lại mà sẽ được chuyển qua kết quả (trong trường hợp tiếp cận dựa trên sự kiện). Nhưng PEP8 cũng nêu rõ: "_Không thống nhất trong một dự án là quan trọng hơn. Tính nhất quán trong một mô-đun hoặc hàm là quan trọng nhất._". Vì vậy, tốt hơn là có thư viện nhất quán, hơn là theo những mong đợi của người khác. – Tadeck

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