-3

i don't understand this error in Python. I read about "self" and "__init__" in this previous question , where says that Python does not pass transparently the instance to the constructor. So I tried a simple class definition and then declare a new instance.

#Basic class
class Testing:
    atr1 = 33
    def __init__():
        pass
    def sayHi():
        print("Hello world")

When I try to declare a new instance of this class, Jupyter throws this error:

t1 = Testing() 

TypeError                                 Traceback (most recent call last)
<ipython-input-6-0019e8f92b90> in <module>
----> 1 t1 = Testing()

TypeError: __init__() takes 0 positional arguments but 1 was given

So for me, this error doesn't make sense, otherwise, Python would be actually passing the instance itself as an argument when initializes the new instance and because i'm not giving an explicit argument. The solution is quite simple: just write "self" as an argument of init method, but i'm still confused about the error. Hope somebody can explain me this weird error message u.u

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • 2
    Python does not implicitly declare the `self` argument for an instance method, but it passes it when you call the constructor, so you should declare it explicitly, i.e. `def __init__(self):` and similarly `def sayHi(self):`. `t1 = Testing()` will construct an instance then pass the newly created instance to the `__init__` method. – Selcuk Sep 16 '21 at 02:27
  • 1
    " Python would be actually passing the instance itself as an argument when initializes the new instance" **that's exactly what is happening**. `__init__` is an instance method, it gets passed the instance as the first positional argument. This goes for **all instance methods in Python**. That is what makes them instance methods – juanpa.arrivillaga Sep 16 '21 at 02:29
  • 1
    " where says that Python does not pass transparently the instance to the constructor." That isn't what it is saying, as far as I can tell. I'm not even sure what you mean by "transparently" in this context. But whatever you mean, **python passes the instance to the first positional argument of a method** – juanpa.arrivillaga Sep 16 '21 at 02:31
  • 2
    You've misunderstood the answers to the question you linked. Those answers say that where many other languages pass the instance as a hidden parameter to methods, Python passes it as an *explicit* parameter, which you have to declare. You've interpreted those answers as saying that Python doesn't pass the instance as a parameter at all. – user2357112 Sep 16 '21 at 02:31

1 Answers1

0

The first parameter to an object method is a reference to the object itself. Traditionally its called self but really you could name it anything you want. In the end, a method is really just a function assigned to a class. That's what happened when you did

class Testing:

    def __init__():
        pass

The def caused python to compile a function and assign it to __init__. Because __init__ is in the Testing class namespace, it assigned it to the class. You could just as easily have done

class Testing:
    pass

def whatever():
    pass

Testing.__init__ = whatever

So, the idea of python just magically creating the self parameter on methods doesn't work. It would be a crazy rule for regular functions.

__init__ is an initializer, not a constructor. The object has been constructed to the point that it has a functioning self by the time __init__ has been called. Classes also have a __new__ that can be used to construct the object.

tdelaney
  • 73,364
  • 6
  • 83
  • 116