2016-03-20 17 views
8

Biorąc pod uwagę następujące klasy:Przydatność @property w tym przypadku

class BasicRNNCell(RNNCell): 
    """The most basic RNN cell.""" 

    def __init__(self, num_units, input_size=None): 
    self._num_units = num_units 
    self._input_size = num_units if input_size is None else input_size 

    @property 
    def input_size(self): 
    return self._input_size 

    @property 
    def output_size(self): 
    return self._num_units 

    @property 
    def state_size(self): 
    return self._num_units 

    def __call__(self, inputs, state, scope=None): 
    """Most basic RNN: output = new_state = tanh(W * input + U * state + B).""" 
    with vs.variable_scope(scope or type(self).__name__): # "BasicRNNCell" 
     output = tanh(linear([inputs, state], self._num_units, True)) 
    return output, output 

Nie rozumiem, dlaczego oni korzystać z funkcji właściwość w tej sprawie. Używanie dekoratora właściwości dla funkcji input_size pozwala wywołać input_size na obiekcie, nazwijmy to komórką, tej klasy, ale dlaczego po prostu nie nazywają one cell._input_size? Czy ktoś może mi powiedzieć, dlaczego jest to przydatne?

+1

Zapytaj autora kodu? Próba wyobrażenia sobie, jak ktoś go używa, aby było użyteczne, jest raczej ... daremnym zadaniem. –

+1

Jest w kodzie Tensorflow napisanym przez google. https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/rnn_cell.py, jestem pewien, że są zajęci robieniem czegoś bardziej przydatnego niż pomoc. – eager2learn

Odpowiedz

6

Korzystanie z właściwości Pythona ma zalety w porównaniu z sugerowanym bezpośrednim dostępem użytkownika.

rozważyć wdrożenie

class Foo(object): 
    def __init__(self): 
     self.bar = ... 

vs.

class Foo(object): 
    def __init__(self): 
     self._bar = ... 

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

Załóżmy, że masz foo = Foo(). W pierwszym przypadku uzyskujesz dostęp do członka jako foo.bar. Oznacza to, że można zrobić

print foo.bar 
foo.bar = 3 

To znaczy, nie masz kontroli nad ograniczając modyfikacje bar. W tym ostatnim przypadku jednak - powołując się na convention not to access things prefixed with _, co prawda - można zrobić

print foo.bar 

ale

foo.bar = 3 

podniesie wyjątek.

Ponadto, przy użyciu property setters można sterować jak bar jest modyfikowany i zrobić walidacji i inne fajne rzeczy:

class Foo(object): 
    def __init__(self): 
     self._bar = ... 

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

    @bar.setter 
    def bar(self, value): 
     if something_of_value(value): 
       raise Whatever 
     self._bar = value 
3

(pokorny trybu opinia: ON)

Myślę, że jego nadużycie właściwościach . W ciągu dnia programiści w językach C++ i Java zdali sobie sprawę, że ujawnianie publicznych członków klasy może sprawić, że ich kod będzie kruchy. Nie można zmienić sposobu generowania danych dla tej zmiennej bez zmiany interfejsu klasy i łamania wstecznej zgodności. Tak więc ludzie zaczęli używać funkcji pobierających i ustawiających (funkcji, które uzyskują dostęp do prywatnych członków) w celu zwiększenia elastyczności, a na wszelki wypadek trzeba było nacisnąć przycisk, aby ukryć wszystkich członków.

Kiedy inne języki miały sformalizowane właściwości, czasami miały ten sam problem z interfejsami klasowymi. Nie można zmienić wartości zmiennej na właściwość bez zmiany interfejsu i po raz kolejny zerwania wstecznej zgodności. Więc na wszelki wypadek popchnęliśmy wszystkie właściwości zmiennych.

Python nie jest taki. Możesz mieć dziś członka foo, zmienić go na właściwość jutro, a interfejs zajęć się nie zmieni. Moim zdaniem jest to po prostu defensywna praktyka kodowania z innego języka i nie jest tu potrzebna.

(tryb skromnej opinii: OFF)

Powiązane problemy