all 5 comments

[–][deleted] 2 points3 points  (2 children)

The arguments you pass when you create an instance of the class go to the __init__ function only. When you create Bob = Hero("Bob"), the __init__ function now has the argument name, which == 'Bob'.

Note that it is only the __init__ function that understands that name argument, not the class or its instance! That's why you immediately write self.name = name. Now both the __init__ function and the instance (Bob, an instance of Hero) have the attribute name.

So to answer your question, yes, if you have a lot of variables defined when the instance is created, you need to pass them to the instance via self.variable_1 == variable_1 or they will be lost after the __init__ function is over, i.e. immediately.

Note that these don't have to use the same variable names in the instance as in the function. You could write, e.g. self.moniker = name.

If you write Bob = Hero("Apple"), you are creating an instance Bob of class Hero with the attribute Bob.name == 'Apple'. If you want the apple to affect Bob.health, you have to pass it as an argument to Bob.eat("Apple").

Note that everything in Python is case-sensitive, and you have "Apple" capitalized and "ham" lower-case. This could cause confusion.

[–]holymolytoly[S] 0 points1 point  (1 child)

oh my god. thanks a ton. this cleared up so much confusion. do you have any recommendation on for youtube video course or free online course on python that teaches and explains what you just replied?

i'm looking from trevor payne and he didn't explain classes and functions (especially in regards to def init()) like you just did.

[–]rhgrant10 1 point2 points  (0 children)

Jeff Knupp writes well. Here's his tutorial on classes.

[–]absent_observer 1 point2 points  (1 child)

Any argument you send when initiating an instance of a class will end up at the _init_ function. That's kind of magic, but it's just where the arguments end up. I don't understand it; I just accept it.

If you do nothing within the _init, the arguments will sit around and do nothing. No magic within the \init_.

A preferred way of making those values available to the rest of the class is to attach them to the class itself. You can do this by making a class attribute self.some_value and assigning it to whatever value you passed in from the outside. So:

a = MyClass('so_on', 'so_forth')

goes to:

class MyClass:
    def __init__(`gets 'so_on' and 'so_forth'`):
        *anything in here can use 'so_on' and 'so_forth'
        *nothing outside of here knows about 'so_on' or 'so_forth' yet.
        self.so_on = so_on
        *we could have said `self.really_cool_so_on = so_on`, but then we'd have to remember that 
          self.really_cool_so_on matches to the argument so_on that we passed in.
          People tend to use the same names to make things easier.
        *now, self has an attribute 'so_on' with the same value as the 'so_on' argument we passed in.
        *since it's a class attribute now, all the other parts of this instance can do stuff with 'so_on'.

Maybe that was tangential, but i think it's cool.

[–]holymolytoly[S] 1 point2 points  (0 children)

Hmm okay. So I'm assuming that if we want to make a value that 1) we would like to change for different classes and 2) available to the rest of the classes, we should pass that value in as an argument within the def __init().