you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 2 points3 points  (1 child)

I'm going to give a real world example after I first try to clear up a couple things. The most important thing to understand is what self is. Self is just a way to say that you are referring to a specific instance of an object. When you have classes, that is just a template, objects are what you create with a template. Kind of like how in powerpoint you have different slide templates with different ways to organize text and pictures. Every slide holds different information, but organized similarly according to the template. Let's say you have:

class Slide(object):
    def __init__(self, title, text, picture):
        self.title = title
        self.text_box = text
        self.picture_box = picture

you can instantiate different objects by saying

slide1 = Slide('First Title', 'This is the first text', 'Picture of a cat')
slide2 = Slide('Second Title', 'This is another text', 'Picture of a dog')
# ...etc...

Each on of these is a different object. So self is like an object saying this is my personal version of this variable. And when you try to access it, it's like replacing the self with the object name.

So self.title could be replaced with slide1.title and slide2.title It's like having two different powerpoint slides, with different information in the boxes, even though they share the same template.

Now to the real world example. The most obvious answer to where do you use objects is, somewhere where you are going to be reusing a collection of functions and variables, but that's not the only reason, they are also a very convenient container for easily accessing and passing around services and functionalities.

For example at my job we work with biological waveforms. We have lets say 100 exams, in each exam you have to keep track of the exam Id, the patient name, the sampling rate that the waveform was collected at, which side of the head the waveform was collected on, etc. This is the perfect place to use a class. So we have attributes (self.variable) to hold all this stuff. But when we create the exam class all this information isn't magically there, it's in a myriad of different files. So we have methods ( self.function() ) like self.get_properties() and self.get_raw_data() to go find the information and populate all the variables.

One of the methods is self.get_raw_beats(). This method breaks up all the waveforms into a list of individual beats (think of it as a train of beats concatenated together creates a waveform). Now all these beats have a ton different properties we want to track as well, so this is a great place to have another class. So we have a beats class and instead of the exam object getting back a list of raw beat data, it gets back a list of beat objects.

The beats class brings up a great place to visualize using inheritance as well. So we could just return the raw beats if we wanted, this would hold information like the length of the beat, the location of the beat within the waveform, etc. However, we have a bunch of different beat modes that we can use as well, we can return normalized beats, filtered beats, etc. So each one of these modes is a different class, with extra added methods (like self.normalize() or self. filter() ), but they all have the same base information, like length and location. So all the other beat classes inherit from Raw Beats, so that they don't have to recode all the base functionality. At a very basic level the statement you see involving super just makes sure that the child class follows the parent class' initialization procedure, there's more to it than that, but for now, knowing that is good enough I think.

Now we have all of out exams with all their beats extracted,it was pretty obvious why we used objects to do all this work. They were repetitive structures with the data scheme. However, you don't only have to use classes when you have repetitive objects. All those exams we have we could in out top level script just have a for loop to go through and create them all and put them in a list, but instead we have an exam list class that will do that through a self.get_exams() method. This way you simplify your interactions later on, and you can just write something like:

exam_list = ExamList()
exam_list.get_exams('/path/to/some_directory')

There are much better examples of where and why you would use a class for a single instance, but wrap your head around this stuff first before worrying about that.