2016-01-29 4 views
1

У меня никогда не было формальной инструкции ООП, и я просто натолкнулся на основные принципы в python, но на перекрестке. Когда вы работаете с экземпляром объекта класса, лучше ли назначать атрибуты с помощью методов или же методы просто возвращают значения? Я много читал о том, чтобы не допустить, чтобы состояние объекта вышло из строя, но не может найти лучшего способа. Вот простой пример:Возвращаемые переменные и присвоение атрибутов

import magic 
class Histogram(): 
    def __init__(self,directory): 
     self.directory = directory 

    # Data Option 1 
    def read_data(self): 
     data = [] 
     file_ref = open(self.directory,'r') 
     line = file_ref.readline() 
     while line: 
      data.append(line) 
      line = file_ref.readline() 
     return data 

    # Data Option 2 
    def set_data(self): 
     data = [] 
     file_ref = open(self.directory,'r') 
     line = file_ref.readline() 
     while line: 
      data.append(line) 
      line = file_ref.readline() 
     self.data = data 



    # Hist Option 1 
    def build_histogram(self): 
     data = self.read_data() 

     # It's not important what magic.histogram does. 
     self.histogram = magic.histogram(data) 

    # Hist Option 2 
    def get_histogram(self,data): 
     return magic.histogram(data) 

    # Hist Option 3 - this requires self.get_data() to have already run. 
    def build_histogram_2(self): 
     self.histogram = magic.histogram(self.data) 

Так Опция Data 1 вынуждает пользователя или вызвать, что и хранить его где-то использовать в сочетании с Hist Вариант 2 или хранить его в self.data для использования с Hist Вариант 3. Data Option 2 позволяет использовать опцию Hist Option 3, но вам все равно придется запускать set_data.

Так что мой реальный вопрос: для класса с методами делать разные вещи, которые часто МОГУТ, НО НЕ ИМЕЮТСЯ цепью вместе, как мне его написать? Неявно задавать атрибуты и рисковать тем, что государство перепуталось? Возвращаемые переменные и пусть «Пользователь» установил их? Есть ли получатели для атрибутов, которые используют мои методы, и если атрибуты не существуют, это как-то?

Пожалуйста, дайте мне знать, если вам нужно лучшее объяснение или другой пример или что-то еще.

+2

Я не думаю, что на это есть простой ответ. Это зависит от того, что вы пытаетесь сделать, и это субъективно. – Duncan

+0

Это то, чего я ожидал, так как я постоянно возвращался туда и обратно по тому, как я хочу справиться с этим: (Но, если сказать, что любой из этих подходов плох? Например, требуя неявно для запуска метода для того, чтобы другой метод, чтобы иметь возможность фактически использовать результат из первого метода? – KevinShaffer

+1

Все остальное равно, вариант 1 имеет некоторые преимущества по сравнению с читабельностью и легкостью тестирования. –

ответ

2

Задайте вопрос, что представляет объект. Имеют ли эти данные разумное отношение к самому объекту?

В этом случае я бы сказал, что да. Ваш параметр данных 2 загружает данные, которые разумно «принадлежат» объекту гистограммы, хотя было бы разумно утверждать, что конструктор должен просто загрузить его, а не требовать отдельного вызова метода для этого.

Кроме того, если вы идете в другую сторону, это не предмет; вы просто используете инфраструктуру объекта для сбора некоторых связанных подпрограмм.

1

Я думаю, что если значение может быть использовано многими методами, вы лучше установите его на экземпляр (init). Если вам нужно рассчитать каждый раз, когда вы собираетесь его использовать, вам не нужно, чтобы он был атрибутом (просто переменной), и он должен быть рассчитан, когда вы собираетесь его использовать.

В конце концов, я попытался бы сделать так, чтобы мой объект был как конечный автомат, где вы не знаете, какие методы вы можете или не можете вызвать в какой-то момент, потому что вы не знаете, какие значения вы уже рассчитали.