2012-04-29 48 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']) 

運行:內置非數據版本的屬性?

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

Books.referTablebeing a data descriptor不受book.__dict__['referTable']陰影:

property()的功能被實現爲一個數據描述符。 因此,實例不能重寫屬性的行爲。

要隱藏它,而不是property內置描述符我必須使用我自己的描述符。是否有像property這樣的內置描述符,但它是非數據?

+1

你想在這裏做什麼?你想通過改變你在函數上使用'@ property''的函數來實現這個目標是不可能實現的? –

+0

@Lattyware,我試圖做一個懶惰的描述符。有時我想'referTable'在'__init__'中設置。在其他情況下,我希望描述符計算值,並以'__init__'中的方式重寫描述符。在這裏(http://blog.pythonisito.com/2008/08/lazy-descriptors.html),它是一個單獨的描述符,這對我來說很有用。在我的情況下,我想簡化它,如果可能的話使用內置的描述符,而'property'不適合我。 – warvariuc

+0

'簡化它'?你能否澄清你想簡化的內容?爲什麼你鏈接的例子不適合你? –

回答

5

爲了擴大對我的評論,爲什麼不簡單地是這樣的:

>>> 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 

現在,我想指出,我不認爲這是很好的設計,你要好得多關閉使用私有變量而不是直接訪問__dict__。 E.g:

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

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

總之,答案是否定的,有沒有替代property(),在你的Python標準庫所希望的方式工作。

2

也有一些是非常相似的內置非數據描述符 - class屬性:

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 

如果你需要的東西更像是一個屬性(例如,你想要的功能做一些重型起重第一次,但然後使用該第一個值對未來的所有引用),那麼你就需要建立它自己:

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 

結果如下:

{} 
calculating 
120 
{'referTable': 120} 
120