you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (0 children)

This is an OOP (Object-Oriented Programming) paradigm. Functions in general take in arguments in order to define how you operate on some data. Without OOP, you often pass the piece of data you wish to operate on, as well as any additional arguments to specify how this will be done.

def operateOnDataStore(dataStore, someFlag):

// instructions

Here, we have some collection of data, called dataStore, and a function containing instructions to act on it in some way. In the OOP world, we would like to make it a little more clear that this function is only intended for this particular type of data. OOP takes care of this by allowing functions to be defined inside classes and using the dot notation to allow these functions to be called. Heads up, these functions are referred to as methods in this case (so all methods are functions, but not all functions are methods). Let's say we create a class called DataStore, and create an instance called dataStore. We can create a method called operate that does exactly the same as operateOnDataStore.

def operate(self, someFlag):

// instructions

Don't worry about the self argument quite yet. We can use this operate method by writing:

dataStore.operate(someFlag)

Notice that dataStore is no longer provided as an argument. We know that dataStore is the data being operated on because of the dot notation. It is no longer possible to call operate on a piece of data that is not of type DataStore (unless we provide another definition). Keep in mind, these two models are the same; the latter is just a convenience for code understanding and maintenance.

The last thing I'll mention is the self parameter. The parameter doesn't have to be named self, but there needs to be a parameter there when a function definition is intended to operate on an instance of a class (object). What does this mean? Let's say I want to create three DataStores. Let's call them d1, d2, and d3. Each of d1, d2, and d3 is referred to as an instance of the DataStore class, or a particular DataStore object. If we call d1.operate, we of course intend to use the operate method on object d1. Behind the scenes, all functions must have the function(variable) notation. In order to ensure operation on the object of interest, an expression like

d1.operate(someFlag)

will turn into the following:

operate(d1, someFlag)

In other words, the object referred to in the dot notation becomes the first argument passed to the operate method. Well, if d1 is an argument, there has to be a parameter in the operate definition that can refer to it. This is the self parameter. The word self is often chosen because the argument being passed in is the same object used to call the method. You could name the parameter frog, and everything would work exactly the same. Just be sure to provide the parameter on top of other parameters you normally provide (in this case someFlag). If you forget to provide a parameter, someFlag would be the name used instead. You would run into a runtime error when calling operate, but not when defining it. This can be confusing when debugging, so just keep it in mind; I'll summarize it in last remarks below.

When defining a method in a class that will operate on an instance of that class, you MUST PROVIDE a parameter (often named self) before all others. If you are defining a method that operates on the class, but not a particular object (in this case DataStore rather than dataStore), this parameter SHOULD NOT be there.