__init__ explanation please

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Erik Lind

    __init__ explanation please

    I'm new to Python, and OOP. I've read most of Mark Lutz's book and more
    online and can write simple modules, but I still don't get when __init__
    needs to be used as opposed to creating a class instance by assignment. For
    some strange reason the literature seems to take this for granted. I'd
    appreciate any pointers or links that can help clarify this.

    Thanks


  • Daniel Fetchinson

    #2
    Re: __init__ explanation please

    I'm new to Python, and OOP. I've read most of Mark Lutz's book and more
    online and can write simple modules, but I still don't get when __init__
    needs to be used as opposed to creating a class instance by assignment. For
    some strange reason the literature seems to take this for granted. I'd
    appreciate any pointers or links that can help clarify this.
    I'm not sure if I understand your question correctly but maybe this will help:

    If you want code to be run upon creating an instance of your class you
    would use __init__. Most common examples include setting attributes on
    the instance and doing some checks, e.g.

    class Person:
    def __init__( self, first, last ):
    if len( first ) 50 or len( last ) 50:
    raise Exception( 'The names are too long.' )
    self.first = first
    self.last = last

    And you would use your class like so,

    p1 = Person( 'John', 'Smith' )
    p2 = Person( "Some long fake name that you don't really want to
    except, I don't know if it's really longer than 50 but let's assume it
    is", "Smith" )
    # This last one would raise an exception so you know that something is not okay

    HTH,
    Daniel

    Comment

    • Colin J. Williams

      #3
      Re: __init__ explanation please

      Erik Lind wrote:
      I'm new to Python, and OOP. I've read most of Mark Lutz's book and more
      online and can write simple modules, but I still don't get when __init__
      needs to be used as opposed to creating a class instance by assignment. For
      some strange reason the literature seems to take this for granted. I'd
      appreciate any pointers or links that can help clarify this.
      >
      Thanks
      >
      >
      You don't always need __init__ if
      __new__ is used with a "new" class.

      Colin W.

      Comment

      • Daniel Fetchinson

        #4
        Re: __init__ explanation please

        Please keep discussion on the list......
        I'm not sure if I understand your question correctly but maybe this will
        help:

        If you want code to be run upon creating an instance of your class you
        would use __init__. Most common examples include setting attributes on
        the instance and doing some checks, e.g.

        class Person:
        def __init__( self, first, last ):
        if len( first ) 50 or len( last ) 50:
        raise Exception( 'The names are too long.' )
        self.first = first
        self.last = last

        And you would use your class like so,

        p1 = Person( 'John', 'Smith' )
        p2 = Person( "Some long fake name that you don't really want to
        except, I don't know if it's really longer than 50 but let's assume it
        is", "Smith" )
        # This last one would raise an exception so you know that something is not
        okay

        HTH,
        Daniel
        >
        Is not the code run when I create an instance by assignement somewhere else?
        >
        I take the point that one might want to check for potential exceptions
        immediately, but most examples in the literature aren't doing that and don't
        seem to be doing anything that would not be done when creating an instance
        by assignment later somewhere. I'm missing something basic here.
        What do you mean by "create an instance by asignment somewhere else"?

        Comment

        • Jeroen Ruigrok van der Werven

          #5
          Re: __init__ explanation please

          -On [20080113 01:41], Erik Lind (elind@spamcop. net) wrote:
          >I'm new to Python, and OOP. I've read most of Mark Lutz's book and more
          >online and can write simple modules, but I still don't get when __init__
          >needs to be used as opposed to creating a class instance by assignment.
          I personally tend to see __init__ or __new__ as equivalent to what other
          languages call a constructor.

          (And I am sure some people might disagree with that. ;))

          --
          Jeroen Ruigrok van der Werven <asmodai(-at-)in-nomine.org/ asmodai
          イェルーン ラウフロッ ク ヴァン デル ウェルヴェ ン
          http://www.in-nomine.org/ | http://www.rangaku.org/
          The riddle master himself lost the key to his own riddles one day, and
          found it again at the bottom of his heart.

          Comment

          • Fredrik Lundh

            #6
            Re: __init__ explanation please

            Jeroen Ruigrok van der Werven wrote:
            I personally tend to see __init__ or __new__ as equivalent to what other
            languages call a constructor.
            >
            (And I am sure some people might disagree with that. ;))
            given that they do different things, I'm not sure it's that helpful to
            describe them *both* as constructors.

            </F>

            Comment

            • Fredrik Lundh

              #7
              Re: __init__ explanation please

              Erik Lind wrote:
              I'm new to Python, and OOP. I've read most of Mark Lutz's book and more
              online and can write simple modules, but I still don't get when __init__
              needs to be used as opposed to creating a class instance by assignment.
              nothing is ever created by plain assignment in Python; to create a class
              instance in Python, you *call* the class object. an example:

              class MyClass:
              pass

              # create three separate instances
              obj1 = MyClass()
              obj2 = MyClass()
              obj3 = MyClass()

              (it's the () that creates the object, not the =)

              if you want to initialize the method's state (that is, set some
              attributes), you can do that from the outside:

              obj1.attrib = "some value"

              or in an "initialization " method in the class:

              class MyClass:
              def init(self):
              self.attrib = "some value"

              obj1 = MyClass()
              obj1.init()

              but in both cases, you'll end up with an inconsistent object state (in
              this case, no attribute named "attrib") if you forget to do this.

              obj1 = MyClass()
              print obj1.attrib # this will fail

              to avoid such mistakes, you can use __init__ instead. this is just a
              initialization method that's automatically called by Python *after* the
              object is created, but *before* the call to the class object returns.

              class MyClass:
              def __init__(self):
              self.attrib = "some value"

              obj1 = MyClass()
              print obj1.attrib # this will succeed

              also, any arguments that you pass to the class object call are passed on
              to the initialization method.

              class MyClass:
              def __init__(self, value):
              self.attrib = value

              obj1 = MyClass("hello" )
              print obj1.attrib # prints "hello"

              as Jeroen points out, this is pretty much the same thing as a
              constructor in other languages -- that is, a piece of code that's
              responsible for setting up an object's state.

              Python's a bit different; the object is in fact created before the
              call to __init__, but this doesn't matter much in practice; if
              construction fails, the assignment will fail, so the object will be
              lost, and is reclaimed by the GC later on.

              (unless you explicitly store a reference to the object somewhere else,
              of course:
              >>class MyClass:
              .... def __init__(self):
              .... global secret
              .... secret = self
              .... raise ValueError("oop s! failed!")
              .... def method(self):
              .... print "here I am!"
              ....
              >>obj = MyClass()
              Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
              File "<stdin>", line 5, in __init__
              ValueError: oops! failed!
              >>obj
              Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
              NameError: name 'obj' is not defined
              >>secret.method ()
              here I am!

              )

              finally, if you want full control also over the actual creation of the
              object, more recent Python versions support a __new__ method that can be
              used instead of __init__, or as a complement. but that's an advanced
              topic, and is nothing you need to worry about while trying to the hang
              of class basics.

              hope this helps!

              </F>

              Comment

              • Ben Finney

                #8
                Re: __init__ explanation please

                Jeroen Ruigrok van der Werven <asmodai@in-nomine.orgwrite s:
                -On [20080113 01:41], Erik Lind (elind@spamcop. net) wrote:
                I'm new to Python, and OOP. I've read most of Mark Lutz's book and
                more online and can write simple modules, but I still don't get
                when __init__ needs to be used as opposed to creating a class
                instance by assignment.
                >
                I personally tend to see __init__ or __new__ as equivalent to what
                other languages call a constructor.
                That's getting the two of them confused. __new__ is a constructor,
                __init__ is not.
                (And I am sure some people might disagree with that. ;))
                It isn't really a matter for much debate.

                <URL:http://www.python.org/doc/ref/customization.h tml>

                __new__ is the constructor: it creates the instance and returns it.

                Along the way, it calls __init__ on the *already-created* instance, to
                ask it to initialise itself ready for use. So, __init__ is an
                "initialise r" for the instance.

                Python, unlike many other OO languages, fortunately has these two
                areas of functionality separate. It's far more common to need to
                customise instance initialisation than to customise creation of the
                instance. I override __init__ for just about every class I write; I
                can count the number of times I've needed to override __new__ on the
                fingers of one foot.

                --
                \ "Reichel's Law: A body on vacation tends to remain on vacation |
                `\ unless acted upon by an outside force." -- Carol Reichel |
                _o__) |
                Ben Finney

                Comment

                • A.T.Hofkamp

                  #9
                  Re: __init__ explanation please

                  On 2008-01-13, Erik Lind <elind@spamcop. netwrote:
                  I'm new to Python, and OOP. I've read most of Mark Lutz's book and more
                  online and can write simple modules, but I still don't get when __init__
                  needs to be used as opposed to creating a class instance by assignment. For
                  some strange reason the literature seems to take this for granted. I'd
                  appreciate any pointers or links that can help clarify this.
                  I think you mean the following:
                  You'd like to do

                  p = Person('me', 'here', 31)

                  and you are wondering why you need the __init__() function in

                  class Person(object):
                  def __init__(self, name, addres, age):
                  self.name = name
                  self.address = address
                  self.age = age

                  right?

                  If so, the answer is that while you think you are doing "Person('me ', 'here', 31)",
                  you are in reality executing "Person.__init_ _(self, 'me', 'here', 31)", where
                  'self' is refers to a shiny new, empty object created for you.

                  (and the 'self' is obtained by the Person.__new__ function I think, but others
                  here have much better knowledge about this).


                  Sincerely,
                  Albert

                  Comment

                  • Ben Finney

                    #10
                    Re: __init__ explanation please

                    "A.T.Hofkam p" <hat@se-162.se.wtb.tue. nlwrites:
                    while you think you are doing "Person('me ', 'here', 31)", you are in
                    reality executing "Person.__init_ _(self, 'me', 'here', 31)", where
                    'self' is refers to a shiny new, empty object created for you.
                    This is misleading, and founders on many discrepancies, not least of
                    which is that '__init__' always returns None, yet the 'Person()' call
                    returns the new instance. So it's quite untrue to say that one is "in
                    reality" calling the '__init__' method.

                    What one is "in reality" calling is the '__new__' method of the Person
                    class. That function, in turn, is creating a new Person instance, and
                    calling the '__init__' method of the newly-created instance. Finally,
                    the '__new__' method returns that instance back to the caller.

                    --
                    \ "Probably the toughest time in anyone's life is when you have |
                    `\ to murder a loved one because they're the devil." -- Emo |
                    _o__) Philips |
                    Ben Finney

                    Comment

                    • Jeroen Ruigrok van der Werven

                      #11
                      Re: __init__ explanation please

                      -On [20080113 14:03], Ben Finney (bignose+hates-spam@benfinney. id.au) wrote:
                      >That's getting the two of them confused. __new__ is a constructor,
                      >__init__ is not.
                      And there I just sent an email stating the wrong thing.

                      I'll dig into it again, because I am really confusing something here (and
                      jumping between 4 languages on the same day is not helping much to be honest).

                      --
                      Jeroen Ruigrok van der Werven <asmodai(-at-)in-nomine.org/ asmodai
                      イェルーン ラウフロッ ク ヴァン デル ウェルヴェ ン
                      http://www.in-nomine.org/ | http://www.rangaku.org/
                      If slavery is not wrong, nothing is wrong...

                      Comment

                      • Hrvoje Niksic

                        #12
                        Re: __init__ explanation please

                        Ben Finney <bignose+hate s-spam@benfinney. id.auwrites:
                        What one is "in reality" calling is the '__new__' method of the Person
                        class. That function, in turn, is creating a new Person instance, and
                        calling the '__init__' method of the newly-created instance. Finally,
                        the '__new__' method returns that instance back to the caller.
                        This is also not entirely correct. __new__ doesn't call __init__; if
                        it did, there would be no way to call __new__ without also calling
                        __init__ (pickle, among other things, does that and needs to do that
                        to correctly implement its logic).

                        "In reality" executing Person(...) invokes the __call__ method of
                        type(Person) (normally the standard metatype called "type") bound to
                        the Person type object. This is where the logic to call __new__
                        followed by __init__ is implemented, in code that does something close
                        to this:

                        obj = mytype.__new__( *args, **kwds)
                        if isinstance(obj, mytype):
                        mytype.__init__ (obj, *args, **kwds)
                        return obj

                        Comment

                        • Hrvoje Niksic

                          #13
                          Re: __init__ explanation please

                          Wildemar Wildenburger <lasses_weil@kl apptsowieso.net writes:
                          Jeroen Ruigrok van der Werven wrote:
                          >To restate it more correctly: __init__ is akin to a constructor.
                          >>
                          No. See Hrvoje Niksic's reply (and Ben Finney's to which it was a
                          reply).
                          >
                          __init__() /initializes/ an instance (automatically after
                          creation). It is called, /after/ the instance has been constructed
                          I don't understand the purpose of this "correction ". After all,
                          __init__ *is* the closest equivalent to what other languages would
                          call a constructor. Take C++ and Java, the two most popular OO
                          languages in existence. Their constructors also "initialize " an
                          instance -- the actual allocation is left to the caller (new or stack
                          in C++) or to the garbage collector. They even share with Python the
                          convention of not returning the constructed value, they operate purely
                          on side effect, just like Python's __init__. And yet, no one says
                          that they are somehow not constructors because of that.

                          Wikipedia calls the constructor "a special method used in object
                          oriented programming which puts the object's members into a valid
                          state." Again, exactly what __init__ does.

                          Comment

                          • Mel

                            #14
                            Re: __init__ explanation please

                            Hrvoje Niksic wrote:
                            Wildemar Wildenburger <lasses_weil@kl apptsowieso.net writes:
                            >
                            >Jeroen Ruigrok van der Werven wrote:
                            >>To restate it more correctly: __init__ is akin to a constructor.
                            >>>
                            >No. See Hrvoje Niksic's reply (and Ben Finney's to which it was a
                            >reply).
                            >>
                            >__init__() /initializes/ an instance (automatically after
                            >creation). It is called, /after/ the instance has been constructed
                            >
                            I don't understand the purpose of this "correction ". After all,
                            __init__ *is* the closest equivalent to what other languages would
                            call a constructor.
                            Nevertheless, __init__ doesn't construct anything. You can even call
                            it to reinitialize an existing object:


                            Python 2.5.1 (r251:54863, May 2 2007, 16:56:35)
                            [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
                            Type "help", "copyright" , "credits" or "license" for more information.
                            >>class AClass (object):
                            .... def __init__ (self):
                            .... self.a = 4
                            ....
                            >>a = AClass()
                            >>a.a
                            4
                            >>a.a = 5
                            >>a.a
                            5
                            >>a.__init__( )
                            >>a.a
                            4



                            Cheers, Mel.

                            Comment

                            • Hrvoje Niksic

                              #15
                              Re: __init__ explanation please

                              Mel <mwilson@the-wire.comwrites:
                              >I don't understand the purpose of this "correction ". After all,
                              >__init__ *is* the closest equivalent to what other languages would
                              >call a constructor.
                              >
                              Nevertheless, __init__ doesn't construct anything.
                              Only if by "construct" you mean "allocate". __init__ starts out with
                              an empty object and brings it to a valid state, therefore
                              "constructi ng" the object you end up with. That operation is exactly
                              what other languages call a constructor.

                              Comment

                              Working...