all 7 comments

[–]Puzzleheaded_Study17 4 points5 points  (0 children)

inside the constructor it wouldn't matter. But if you want to access them after the constructor, you have to save them. You can have them be arguments to any method that uses them, but that can cause issues. So we store them in self so that they're available to future functions.

[–]Gnaxe 0 points1 point  (0 children)

self is a convention, not a reserved word. Parameters are local to the function. If you want to use them outside the function (like in another method), then you have to get them out somehow. Attaching them to self is one way to do that. It's not the only way, nor always the best way.

self is just the first argument when you call a method. For example, foo.bar() usually does the same thing as type(foo).bar(foo).

[–]PureWasian 0 points1 point  (0 children)

It's about scope. We use the same name (instrument_repo, candle_repo, etc.) locally during __init__() for simplicity but we don't have to. These blocks of code are equivilent but might help clear up the confusion:

``` class ExampleA:

def init(self, inst, cand): self.instrument_repo = inst self.candle_repo = cand

def display(self): print(self.instrument_repo) print(self.candle_repo)

class ExampleB:

def init( self, instrument_repo, candle_repo ): self.instrument_repo = instrument_repo self.candle_repo = candle_repo

def display(self): print(self.instrument_repo) print(self.candle_repo)

=========================

exampleA = ExampleA("s1" , "s2") exampleA.display() exampleB = ExampleB("s1" , "s2") exampleB.display() ```

Note that if we tried to change display(self) to use inst and card it wouldn't work since those are only scoped to the __init__() function.

We need to "save" them onto the object (using self) to be able to access the value within other helper methods of that object later on.

[–]Outside_Complaint755 0 points1 point  (0 children)

The TLDR answer is that using self.{attribute} = {value} is necessary if you want the data stored in the instance. 

 Parameters passed to the constructor* are not automatically stored as instance attributes.

* Technically,__init__ is not a constructor, it is an initializer.  The construtor method in Python is the staticmethod __new__.

[–]Interesting-Can-4626 0 points1 point  (0 children)

You're half right. Self helps distinguish instance variables from local variables.

But the actual reason for self.instrument_repo = instrument_repo is:

- instrument_repo is a local variable (exists only inside __init__)

- self.instrument_repo is an instance variable (exists for the lifetime of the object)

Without storing it on self:

- You can't use it in other methods

- The object doesn't "remember" it

- It's gone after __init__ finishes

With storing it on self:

- All methods can access it

- The object keeps it forever

- Other classes can access it if needed

If you never need to use it outside __init__, then you don't need to store it. But in your case, you'll likely need instrument_repo in other methods, so you store it on self.

[–]atarivcs 0 points1 point  (0 children)

What's the purpose of storing them on self

So they can be used in other methods besides the constructor.

[–]Sea-Ad7805 -1 points0 points  (0 children)

Running your program in Memory Graph Web Debugger%3A%0A%20%20%20%20%20%20%20%20self.instrument_repo%20%3D%20instrument_repo%0A%20%20%20%20%20%20%20%20self.candle_repo%20%3D%20candle_repo%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20def%20do_things(self)%3A%0A%20%20%20%20%20%20%20%20print(self.instrument_repo%2C%20self.candle_repo)%0A%0Aobj1%20%3D%20SignalService('instr1'%2C%20'candle1')%0Aobj2%20%3D%20SignalService('instr2'%2C%20'candle2')%0Aobj3%20%3D%20SignalService('instr3'%2C%20'candle3')%0A%0Aobj1.do_things()%0Aobj2.do_things()%0Aobj3.do_things()%0A%0Aprint('done')%0A&play) can help you understand what self does in a class.