2012-04-29 21 views
9
class Books(): 
    def __init__(self): 
     self.__dict__['referTable'] = 1 

    @property 
    def referTable(self): 
     return 2 

book = Books() 
print(book.referTable) 
print(book.__dict__['referTable']) 

Chạy:Phiên bản phi dữ liệu được tích hợp sẵn?

[email protected]:~/Desktop$ python3 test.py 
2 
1 

Books.referTablebeing a data descriptor không bị che bởi book.__dict__['referTable']:

Chức năng property() được thực hiện như một mô tả dữ liệu. Theo đó, các trường hợp không thể ghi đè hành vi của thuộc tính.

Để tô bóng nó, thay vì property bộ mô tả tích hợp, tôi phải sử dụng trình mô tả của riêng mình. Có một bộ mô tả tích hợp như property nhưng không phải là dữ liệu không?

+1

Bạn đang cố gắng làm gì ở đây? Những gì bạn đang cố gắng để đạt được điều đó không thể đạt được bằng cách thay đổi cách mà hàm bạn đang sử dụng '' @ property'' trên các hàm? –

+0

@Lattyware, tôi đang cố tạo một bộ mô tả lười biếng. Đôi khi tôi muốn 'referTable' được đặt trong' __init__'. Trong các trường hợp khác, tôi muốn bộ mô tả tính toán giá trị và ghi đè lên bộ mô tả giống như cách nó được thực hiện trong '__init__'. Ở đây (http://blog.pythonisito.com/2008/08/lazy-descriptors.html) nó được tạo ra một bộ mô tả riêng biệt cho điều đó, điều này sẽ làm việc cho tôi. Trong trường hợp của tôi, tôi muốn đơn giản hóa nó, sử dụng nếu có thể một bộ mô tả dựng sẵn và 'thuộc tính' không hoạt động đối với tôi. – warvariuc

+0

'Đơn giản hóa'? Bạn có thể làm rõ những gì bạn muốn đơn giản hóa? Tại sao ví dụ bạn liên kết không hoạt động cho bạn? –

Trả lời

5

Mở rộng trên nhận xét của tôi, tại sao không chỉ đơn giản là một cái gì đó như thế này:

>>> class Books(): 
...  def __init__(self): 
...   self.__dict__['referTable'] = 1 
...  @property 
...  def referTable(self): 
...   try: 
...    return self.__dict__['referTable'] 
...   except KeyError: 
...    return 2 
... 
>>> a = Books() 
>>> a.referTable 
1 
>>> del a.__dict__['referTable'] 
>>> a.referTable 
2 

Bây giờ, tôi muốn lưu ý rằng tôi không nghĩ rằng đây là thiết kế tốt, và bạn muốn được tốt hơn sử dụng biến riêng tư thay vì truy cập trực tiếp vào __dict__. Ví dụ:

class Books(): 
    def __init__(self): 
     self._referTable = 1 

    @property 
    def referTable(self): 
     return self._referTable if self._referTable else 2 

Nói tóm lại, câu trả lời là không, không có sự thay thế cho property() mà làm việc theo cách bạn muốn trong thư viện chuẩn của Python.

2

Có gì đó rất giống với một built-in mô tả phi dữ liệu - các thuộc tính lớp:

class Books(): 

    referTable = 'default' 

    def __init__(self, referTable=None): 
     if referTable is not None: 
      self.referTable = referTable 


book = Books() 
print(book.referTable) 
# default 
book.referTable = 'something specific' 
print(book.referTable) 
# something specific 

Nếu bạn cần một cái gì đó giống như một tài sản (ví dụ, bạn muốn có một chức năng để làm một số nặng-nâng lần đầu tiên, nhưng sau đó sử dụng giá trị đầu tiên cho tất cả các tài liệu tham khảo trong tương lai), sau đó bạn sẽ cần phải xây dựng nó cho mình:

class OneTime(object): 

    def __init__(self, method): 
     self.name = method.__name__ 
     self.method = method 

    def __get__(self, inst, cls): 
     if inst is None: 
      return self 
     result = self.method(inst) 
     inst.__dict__[self.name] = result 
     return result 

class Books(object): 

    @OneTime 
    def referTable(self): 
     print 'calculating' 
     return 1 * 2 * 3 * 4 * 5 

b = Books() 
print b.__dict__ 
print b.referTable 
print b.__dict__ 
print b.referTable 

với kết quả như sau:

{} 
calculating 
120 
{'referTable': 120} 
120 
Các vấn đề liên quan