2009-10-06 13 views
6

Używam "property", aby zapewnić, że zmiany w zmiennych instancji obiektów są pakowane metodami, w których potrzebuję.Stałe zmienne instancji?

Co się dzieje, gdy instancja ma zmienną, której logicznie nie należy zmieniać? Np. Jeśli robię klasę dla procesu, każda instancja procesu powinna mieć atrybut pid, który będzie często dostępny, ale nie powinien być zmieniany.

Jaki jest najbardziej Pythonowy sposób obsługi osoby próbującej zmodyfikować tę instancję?

  • Wystarczy zaufać użytkownik nie spróbować zmienić coś, czego nie powinien?

  • Użyj właściwości, ale podnieś wyjątek , jeśli zmienna instancji została zmieniona na ?

  • Coś jeszcze?

+0

http://stackoverflow.com/questions/1358711/raising-an-exception-on-updating-a-stantent-attribute-in-python –

Odpowiedz

6

poprzedzić nazwę zmiennej z __ i utworzyć właściwość tylko do odczytu, Python zadba wyjątków i zmiennej będzie sama być zabezpieczone przed przypadkowym nadpisywanie.

class foo(object): 
    def __init__(self, bar): 
     self.__bar = bar 

    @property 
    def bar(self): 
     return self.__bar 

f = foo('bar') 
f.bar   # => bar 
f.bar = 'baz' # AttributeError; would have to use f._foo__bar 
+0

W dwóch ostatnich wierszach masz na myśli "f.foo" i "f" .foo = 'baz' ", prawda? –

+0

Tak, pomieszałem nazwy zmiennych. Już poprawione. –

+1

Uważam, że ukryte w nazwie "prywatne" atrybuty sprawiają więcej problemów niż są warte. Pojedynczy podkreślnik ułatwi tworzenie podklas, a jednocześnie będzie komunikował się z użytkownikami "nie dotykaj tego". –

1

Być może można zastąpić __setattr__? W wierszu,

def __setattr__(self, name, value): 
    if self.__dict__.has_key(name): 
     raise TypeError, 'value is read only' 
    self.__dict__[name] = value 
3

Po prostu zaufanie użytkownika niekoniecznie jest złe; jeśli właśnie piszesz szybki program Pythona do użycia raz i wyrzucony, możesz bardzo dobrze tylko zaufać temu, że użytkownik nie zmienia pola pid.

IMHO najbardziej Pythonicznym sposobem wymuszenia pola tylko do odczytu jest użycie właściwości podnoszącej wyjątek przy próbie ustawienia pola.

Tak więc, IMHO masz dobry instynkt na ten temat.

1

Po prostu użyj właściwości i ukrytego atrybutu (poprzedzonego przedrostkiem jedno podkreślenie).

Proste właściwości są tylko do odczytu!

>>> class Test (object): 
... @property 
... def bar(self): 
... return self._bar 
... 
>>> t = Test() 
>>> t._bar = 2 
>>> t.bar 
2 
>>> t.bar = 2 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: can't set attribute 

Ukrywanie z podwójnym podkreśleniem nie służy do ukrywania implementacji, ale upewnij się, że nie kolidują z podklasy atrybutów; rozważmy na przykład mixin, to musi być bardzo ostrożne!

Jeśli chcesz ukryć atrybut, użyj pojedynczego podkreślenia. I jak widzisz, nie ma dodatkowej magii do dodania - jeśli nie zdefiniujesz funkcji set, twoja własność jest tak samo czytelna jak wartość zwracana przez metodę.

Powiązane problemy