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

Bieg:Wbudowana wersja własności bez danych?

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

Books.referTablebeing a data descriptor nie jest zasłonięta przez book.__dict__['referTable']:

Funkcja property() jest zaimplementowany jako deskryptor danych. W związku z tym instancje nie mogą przesłonić zachowania właściwości.

Aby go śledzić, zamiast wbudowanego deskryptora należy użyć własnego deskryptora, a nie property. Czy istnieje wbudowany deskryptor taki jak property, ale który nie jest danych?

+1

Co próbujesz tutaj zrobić? Czego próbujesz osiągnąć, czego nie można osiągnąć zmieniając sposób, w jaki używasz funkcji '' @ property'' na funkcjach? –

+0

@ Legatware, próbuję zrobić leniwy deskryptor. Czasami chcę ustawić 'referTable' w' __init__'. W innych przypadkach chcę, aby deskryptor obliczył wartość i nadpisał deskryptor w taki sam sposób jak w '__init__'. Tutaj (http://blog.pythonisito.com/2008/08/lazy-descriptors.html) jest to osobny deskryptor, który będzie dla mnie działał. W moim przypadku chcę go uprościć, używając w miarę możliwości wbudowanego deskryptora, a "właściwość" nie działa dla mnie. – warvariuc

+0

"Uprość to"? Czy możesz wyjaśnić, co chcesz uprościć? Dlaczego przykładowy link nie działa dla Ciebie? –

Odpowiedz

5

Aby rozwinąć na mój komentarz, dlaczego nie po prostu coś takiego:

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

Teraz, chciałbym zauważyć, że nie sądzę, że to jest dobry projekt, a byłbyś znacznie lepiej wyłączyć za pomocą zmiennej prywatnej, a nie bezpośrednio uzyskać dostęp do __dict__. Np:

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

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

Krótko mówiąc, odpowiedź brzmi: nie, nie ma alternatywy do property(), który działa w sposób chcesz w bibliotece standardowej Pythona.

2

Jest coś bardzo podobny do wbudowanego w deskryptorze non-danych - atrybut Klasa:

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 

Jeśli potrzebujesz czegoś więcej jak posesji (na przykład, chcesz zrobić kilka funkcji ciężkich podnoszenia po raz pierwszy, ale następnie użyć tej pierwszej wartości odniesienia dla wszystkich przyszłych), a następnie trzeba będzie budować siebie:

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 

z następującymi wynikami:

{} 
calculating 
120 
{'referTable': 120} 
120 
Powiązane problemy