2

I never got formal OOP instruction, and just kinda stumbled my way through the basics in python, but am at a crossroads. When dealing with an instantiated class object, is it better to assign attributes via methods, or have the methods just return the values? I've read a lot about not letting the object's state get out of whack, but can't figure out the best way. Here's a simple example:

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)

So Data Option 1 forces the user to either call that and store it somewhere to use in conjunction with Hist Option 2 or store it in self.data to use with Hist Option 3. Data Option 2 lets you use Hist Option 3, but you still have had to already run set_data.

So my real question is, for a class with methods to do different things, that often CAN but don't HAVE to be chained together, how should I write it? Implicitly setting attributes and risk getting the state messed up? Return variables and let the "User" set them? Have getters for the attributes that my methods use, and if the attributes don't exist handle that somehow?

Please let me know if you need better explanation, or another example or anything.

4
  • 2
    I don't think there's a single simple answer to that. It is going to depend on exactly what you're trying to do, and it's subjective. Commented Jan 29, 2016 at 13:58
  • That's kinda what I expected, since I've constantly went back and forth on how I want to handle it :( But that being said, is any one of these approaches bad? Such as requiring implicitly for a method to run in order for another method to be able to actually use the result from the first method? Commented Jan 29, 2016 at 14:00
  • 1
    Everything else being equal, option 1 has some advantages wrt. readability and ease of testing. Commented Jan 29, 2016 at 14:02
  • I would definitely avoid option 3, and prefer option 1. In a class, I prefer to set all arguments in the __init__, even if it's with None, so you can see all attributes at once. Commented Jan 29, 2016 at 14:18

2 Answers 2

2

Ask what the object represents. Does that data reasonably belong to the object itself?

In this case, I would say yes. Your data option 2 is loading the data which reasonably "belongs to" the histogram object -- although it would be reasonable to argue that the constructor ought just load it rather than requiring a separate method call to accomplish that.

Also, if you go the other way, this is not really an object; you're simply using the object framework to collect some related subroutines.

Sign up to request clarification or add additional context in comments.

Comments

1

I think if the value might be used by many methods you better set it on instantiation (init). If you need to calculate every time you are going to use it, then you don't need it to be an attribute (just a variable) and it should be calculated when you are going to use it.

In the end what I would try to do is avoiding my object to be like a state machine, where you don't know what methods you can or can't call at some moment because you don't know what values you have already calculated.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.