2016-03-20 16 views
8

Với lớp sau đây:Tính hữu dụng của @property trong trường hợp này

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 

Tôi không hiểu tại sao họ sử dụng chức năng sở hữu trong trường hợp này. Sử dụng trình trang trí đặc tính cho hàm input_size cho phép một hàm gọi input_size trên một đối tượng, chúng ta hãy gọi nó là ô, của lớp đó, nhưng tại sao chúng không chỉ đơn giản gọi hàm cell._input_size? Ai có thể cho tôi biết tại sao điều này hữu ích?

+1

Hỏi tác giả của mã? Đang cố gắng tìm cách một người nào đó sử dụng nó để làm cho nó hữu ích hơn là ... nhiệm vụ vô ích. –

+1

Nó nằm trong mã Tensorflow, được viết bởi google. https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/rnn_cell.py, khá chắc chắn họ đang bận làm điều gì đó hữu ích hơn giúp tôi. – eager2learn

Trả lời

6

Việc sử dụng các thuộc tính Python có lợi thế so với quyền truy cập thành viên trực tiếp mà bạn đề xuất.

Xem xét việc thực hiện

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

vs

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

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

Giả sử bạn có foo = Foo(). Trong trường hợp trước đây, bạn truy cập vào thành viên là foo.bar. Điều này có nghĩa là bạn có thể làm

print foo.bar 
foo.bar = 3 

I.e, bạn không có quyền kiểm soát giới hạn sửa đổi đối với bar. Trong trường hợp sau, mặc dù - dựa trên convention not to access things prefixed with _, phải thừa nhận là - bạn có thể làm

print foo.bar 

nhưng

foo.bar = 3 

sẽ nâng cao một ngoại lệ.

Hơn nữa, sử dụng property setters, bạn có thể kiểm soát cách bar được sửa đổi, và làm kiểm chứng thực và các công cụ mát khác:

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

(khiêm tốn chế độ quan điểm: ON)

Tôi nghĩ rằng một sự lạm dụng của thuộc tính . Quay trở lại trong ngày, các lập trình viên C++ và Java nhận ra rằng việc phơi bày các thành viên lớp công khai có thể làm cho mã của họ trở nên mong manh. Bạn không thể thay đổi ý định về cách dữ liệu cho biến đó được tạo ra mà không thay đổi giao diện lớp và phá vỡ tính tương thích ngược. Vì vậy, mọi người bắt đầu sử dụng getters và setters (các chức năng truy cập các thành viên riêng) để tăng tính linh hoạt và có một sự thúc đẩy để ẩn tất cả các thành viên ... chỉ trong trường hợp.

Khi các ngôn ngữ khác đã chính thức hóa các thuộc tính, đôi khi chúng có cùng vấn đề với giao diện lớp học. Bạn không thể thay đổi từ một biến thành thuộc tính mà không thay đổi giao diện và một lần nữa phá vỡ khả năng tương thích ngược. Vì vậy, đã có một sự thúc đẩy để làm cho tất cả các thuộc tính biến ... chỉ trong trường hợp.

Python không phải như vậy. Bạn có thể có thành viên foo hôm nay, thay đổi thành tài sản vào ngày mai và giao diện lớp học không thay đổi. Để mắt của tôi, đây chỉ là một thực hành mã hóa phòng thủ từ một ngôn ngữ khác và không cần thiết ở đây.

(chế độ ý kiến ​​khiêm tốn: TẮT)

Các vấn đề liên quan