2012-01-03 31 views
14

Tại sao phương pháp __get__ trong một số python descriptor chấp nhận lớp chủ sở hữu làm đối số thứ ba? Bạn có thể đưa ra một ví dụ về việc sử dụng nó không?Tại sao một phương thức mô tả python __get__ chấp nhận lớp chủ sở hữu là một arg?

Đối số đầu tiên (self) là tự hiển nhiên, thứ hai (instances) có ý nghĩa trong bối cảnh mô hình mô tả thường thấy (ví dụ để làm theo), nhưng tôi đã không bao giờ thực sự nhìn thấy thứ ba (owner) được sử dụng. Ai đó có thể giải thích trường hợp sử dụng là gì?

Chỉ cần bằng cách tham khảo và câu trả lời điều kiện này là việc sử dụng điển hình của mô tả tôi đã nhìn thấy:

class Container(object): 
    class ExampleDescriptor(object): 
     def __get__(self, instance, owner): 
      return instance._name 
     def __set__(self, instance, value): 
      instance._name = value 
    managed_attr = ExampleDescriptor() 

Cho rằng instance.__class__ có sẵn tất cả tôi có thể nghĩ đến là đi qua một cách rõ ràng lớp có cái gì đó để làm với việc truy cập trực tiếp bộ mô tả từ lớp thay vì một cá thể (ví dụ: Container.managed_attr). Mặc dù vậy tôi không rõ ràng về những gì người ta sẽ làm trong __get__ trong tình huống này.

Trả lời

9

owner được sử dụng khi thuộc tính được truy cập từ lớp thay vì phiên bản của lớp, trong trường hợp này instance sẽ là None.

Trong ví dụ của bạn, hãy thử làm như sau: print(Container.managed_attr) sẽ không thành công vì instanceNone vì vậy instance._name sẽ tăng AttributeError.

Bạn có thể cải thiện hành vi này bằng cách kiểm tra xem instance is None và có thể hữu ích cho việc ghi nhật ký hoặc đưa ra một ngoại lệ hữu ích hơn để biết mô tả thuộc lớp nào, do đó thuộc tính owner. Ví dụ:

 def __get__(self, instance, owner): 
      if instance is None: 
       # special handling for Customer.managed_attr 
      else: 
       return instance._name 
+1

"ghi nhật ký hoặc tăng ngoại lệ hữu ích hơn" Cảm ơn. – Finn

+0

Tại sao cũng không triển khai thuộc tính cấp lớp được quản lý? Ví dụ, khi một thuộc tính dữ liệu lớp hiện có sẽ được hưởng lợi từ việc được nhìn thấy trong các đơn vị khác nhau. Nói, Room.default_temperature_C, Room.default_temperature_F? Nó không phải là trường hợp sử dụng rõ ràng hơn, hay tôi đang thiếu một cái gì đó? – max

+0

@max: bạn đang thiếu một cái gì đó;) - hỏi nó như là một câu hỏi thường xuyên nếu bạn muốn có một câu trả lời chi tiết. –

1

Có, nó được sử dụng để trình mô tả có thể thấy Vùng chứa khi Container.managed_attr được truy cập. Bạn có thể trả lại một số đối tượng phù hợp với trường hợp sử dụng, như một phương thức không liên kết khi các bộ mô tả được sử dụng để thực hiện các phương thức.

2

Khi trình mô tả được truy cập từ lớp học, instance sẽ là None. Nếu bạn không tính đến tình huống đó (như mã ví dụ của bạn không) thì một lỗi sẽ xảy ra tại thời điểm đó.

Điều gì nên bạn thực hiện trong trường hợp đó? Dù là hợp lý. ;) Nếu không có gì khác có nghĩa là bạn có thể làm theo ví dụ của property và trả về bộ mô tả chính nó khi được truy cập từ lớp đó.

+0

Bất kỳ cơ hội nào bạn có thể giải thích cách trả về bộ mô tả hợp lý cho tài sản? – Finn

+2

@Finn: * Có gì đó * ở đó, vì vậy * một cái gì đó * sẽ được trả lại. Vì không có cá thể nào để lấy giá trị, đối tượng mô tả là lựa chọn tốt nhất tiếp theo. Nếu bạn có một bộ mô tả tùy chỉnh với một giá trị lớp thực tế (mặc định), thì bạn nên trả về giá trị đó khi được truy cập thông qua lớp. –

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