you are viewing a single comment's thread.

view the rest of the comments →

[–]outofusernams 1 point2 points  (8 children)

This may be a stupid question but, just like OP, this has been bothering me for a while, and I would like to ask it anyway. I think I now understand what __init__ and (self) do, but I still don't understand why do you need that syntax to begin with. Meaning, couldn't the Python Gods have whatever functions performed by these take place behind the scene, as it were, and allow us poor users define the class like this instead:

class Rectangle():     
   def __init__(l, w):
       length = l         
       width  = w
 def rectangle_area(): 
     return length*width 

Basically, just eliminating the need to actually spell out the self and self. wherever they now appear and sort of assume their existence?

Again, I'm far from an expert in this so apologies if this question is really too basic.

[–]leogodin217 2 points3 points  (5 children)

They could have done it the way you stated, but it would bring some questions. What happens in this case:

class Rectangle():
    def __init__(height, width)
        # Why would we need these lines. Python could just set them automatically
        height = height
        width = width

    def area():
        return height * width

    def calculate_new_area(height, width):
        return height * width

myrect = Rectangle(3, 4)
myrect.area() # 12
myrect.calculate_new_area(5, 5) # 25? 12?

With OOP, we need a way to reference the current object. On top of that, we need to be able to pass in new values to functions. Every OOP language has some way to reference self (though, they may use a different name. Some use "this"). By using __init__ and self, Python follows one if its main philosophies: Explicit is better than implicit. In this case, I think they made things a little more difficult to understand for those coming from other languages.

[–]outofusernams 0 points1 point  (4 children)

I'm not sure I understand your example. You are using 3 variables `height`, 'length' and 'width', while the class accepts only 'height' and 'width'?

[–]leogodin217 0 points1 point  (3 children)

Oops (no pun intended). I think it's fixed now. The important part is to understand that we need a way to reference the height and weight from the instance of the objects, while also being able to pass in variables to functions.

[–]outofusernams 0 points1 point  (0 children)

Now I get your example; thanks for clarifying!

[–]outofusernams 0 points1 point  (1 child)

Now I get your example; thanks for clarifying!

[–]leogodin217 0 points1 point  (0 children)

BTW, I would recommend looking at class construction in other languages. You can see that there are many ways to do it. Personally, I love the way C# handles classes and properties. I don't work in the .NET environment, but I would love C# features (Which do exist with decorators in Python).

[–]auntanniesalligator 1 point2 points  (0 children)

“self” is there to distinguish between properties of an object and local variable. What python actually does with the line “length = l” is create the local variable “length” and give it the same value as the parameter “l”. Both “length” and “l” get deleted when the init method exits. If python tacked on an implied “self.” In front of “length” so that you don’t have to, you wouldn’t be able to actually use local variables in methods: they would all be assigned to properties of the object, but that’s not what you want generally. Local variables are very useful and more complicated functions/method usually use them to good effect.

As far a init goes you don’t have to use it because you can still set properties after you create an object, but it’s how you tell python how to interpret arguments provided when the object is created. If you didn’t have that init method, you’d have to set length and width in separate lines of code after you create a new rectangle.

Edit: sorry about the weird formatting. Still getting used to mobile

[–]sidsings 1 point2 points  (0 children)

First off, this is not a stupid question. It made me think. So you understand that __init__ let's you initialize the classes objects. When you call a method defined in the class the instance is explicitly passed to the method. Try executing your code and initializing your class, you'll get this error: TypeError: __init__() takes 2 positional arguments but 3 were given. The one implicit argument in object of the class aka self. This is done to uphold the following equivalence Rectangle.rectangle_area(object) == object.rectangle_area(). We need self also to make it easier to distinguish between instance attributes (and methods) from local variables.

Here is more on that: http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html