direct initialization of class attributes vs. declarations w/in __init__

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • digitalorganics@gmail.com

    #1

    direct initialization of class attributes vs. declarations w/in __init__

    What's the difference between initializing class variables within the
    class definition directly versus initializing them within the class's
    __init__ method? Is there a reason, perhaps in certain situations, to
    choose one over the other?

    Thank you.

  • Diez B. Roggisch

    #2
    Re: direct initialization of class attributes vs. declarations w/in__init__

    digitalorganics @gmail.com schrieb:[color=blue]
    > What's the difference between initializing class variables within the
    > class definition directly versus initializing them within the class's
    > __init__ method? Is there a reason, perhaps in certain situations, to
    > choose one over the other?[/color]

    You are confusing class variables with instance variables. The former
    are what you can initialize inside the class-statement. However, they
    are shared amongst _all_ instances. Consider this little example:

    class Foo(object):
    FOO = 1
    BAR = []

    def __init__(self, FOO):
    self.FOO = FOO
    self.BAR.append (FOO)

    def __repr__(self):
    return "FOO: %r\nBAR: %r\n" % (self.FOO, self.BAR)


    f1 = Foo(1)
    print f1
    f2 = Foo(2)
    print f2
    print f1


    ------
    meskal:~/Projects/CameraCalibrato r deets$ python2.4 /tmp/test.py
    FOO: 1
    BAR: [1]

    FOO: 2
    BAR: [1, 2]

    FOO: 1
    BAR: [1, 2]


    -----

    As you can see, the list BAR is shared. And you can also see that
    _assigning_ to something like this:

    self.FOO

    will create an instance-variable. Even if a variable of the same name
    existed on the class before!

    Which is precisely the difference between using variable initialization
    in __init__ and inside the class-statement.

    BTW,

    self.__class__. FOO = value

    will set class-variables inside a method. Just if you wondered.

    Diez

    Comment

    • digitalorganics@gmail.com

      #3
      Re: direct initialization of class attributes vs. declarations w/in __init__

      Ah, you've brought me much clarity Diez, thank you. That would explain
      some "bugs" I've been having...


      Diez B. Roggisch wrote:[color=blue]
      > digitalorganics @gmail.com schrieb:[color=green]
      > > What's the difference between initializing class variables within the
      > > class definition directly versus initializing them within the class's
      > > __init__ method? Is there a reason, perhaps in certain situations, to
      > > choose one over the other?[/color]
      >
      > You are confusing class variables with instance variables. The former
      > are what you can initialize inside the class-statement. However, they
      > are shared amongst _all_ instances. Consider this little example:
      >
      > class Foo(object):
      > FOO = 1
      > BAR = []
      >
      > def __init__(self, FOO):
      > self.FOO = FOO
      > self.BAR.append (FOO)
      >
      > def __repr__(self):
      > return "FOO: %r\nBAR: %r\n" % (self.FOO, self.BAR)
      >
      >
      > f1 = Foo(1)
      > print f1
      > f2 = Foo(2)
      > print f2
      > print f1
      >
      >
      > ------
      > meskal:~/Projects/CameraCalibrato r deets$ python2.4 /tmp/test.py
      > FOO: 1
      > BAR: [1]
      >
      > FOO: 2
      > BAR: [1, 2]
      >
      > FOO: 1
      > BAR: [1, 2]
      >
      >
      > -----
      >
      > As you can see, the list BAR is shared. And you can also see that
      > _assigning_ to something like this:
      >
      > self.FOO
      >
      > will create an instance-variable. Even if a variable of the same name
      > existed on the class before!
      >
      > Which is precisely the difference between using variable initialization
      > in __init__ and inside the class-statement.
      >
      > BTW,
      >
      > self.__class__. FOO = value
      >
      > will set class-variables inside a method. Just if you wondered.
      >
      > Diez[/color]

      Comment

      • digitalorganics@gmail.com

        #4
        Re: direct initialization of class attributes vs. declarations w/in __init__

        Wait a minute! It doesn't explain my bugs. I've got "class variables"
        acting like instance variables. What's weirder is that this behavior
        occurs on my computer (in both of my installed WinXP copies) but not on
        my laptop (WinXP Pro).

        See the following test:

        class Boo:
        jerk = "yes"

        def killjerk(self):
        self.jerk = self.jerk + "no"
        print self.jerk
        print self.__class__. jerk

        bing = Boo()
        bing.killjerk()

        outputs:

        yesno
        yes

        At first, I thought that self.jerk was resolving to the class attribute
        instead of creating a new variable (w/ a differing scope). But we can
        see that there are actually two variables because a direct reference to
        self.__class__. jerk returns "yes", not yesno (what we would get if
        self.jerk pointed to the same data/object as self.__class__. jerk). Yet,
        it's treating self.jerk as a combination of the two (it always add the
        class attribute to the instance attribute). Is this normal behavior??
        It doesn't work this way on my laptop...

        Perhaps you can see why I'd be confused!

        Thanks.

        digitalorganics @gmail.com wrote:[color=blue]
        > Ah, you've brought me much clarity Diez, thank you. That would explain
        > some "bugs" I've been having...
        >
        >
        > Diez B. Roggisch wrote:[color=green]
        > > digitalorganics @gmail.com schrieb:[color=darkred]
        > > > What's the difference between initializing class variables within the
        > > > class definition directly versus initializing them within the class's
        > > > __init__ method? Is there a reason, perhaps in certain situations, to
        > > > choose one over the other?[/color]
        > >
        > > You are confusing class variables with instance variables. The former
        > > are what you can initialize inside the class-statement. However, they
        > > are shared amongst _all_ instances. Consider this little example:
        > >
        > > class Foo(object):
        > > FOO = 1
        > > BAR = []
        > >
        > > def __init__(self, FOO):
        > > self.FOO = FOO
        > > self.BAR.append (FOO)
        > >
        > > def __repr__(self):
        > > return "FOO: %r\nBAR: %r\n" % (self.FOO, self.BAR)
        > >
        > >
        > > f1 = Foo(1)
        > > print f1
        > > f2 = Foo(2)
        > > print f2
        > > print f1
        > >
        > >
        > > ------
        > > meskal:~/Projects/CameraCalibrato r deets$ python2.4 /tmp/test.py
        > > FOO: 1
        > > BAR: [1]
        > >
        > > FOO: 2
        > > BAR: [1, 2]
        > >
        > > FOO: 1
        > > BAR: [1, 2]
        > >
        > >
        > > -----
        > >
        > > As you can see, the list BAR is shared. And you can also see that
        > > _assigning_ to something like this:
        > >
        > > self.FOO
        > >
        > > will create an instance-variable. Even if a variable of the same name
        > > existed on the class before!
        > >
        > > Which is precisely the difference between using variable initialization
        > > in __init__ and inside the class-statement.
        > >
        > > BTW,
        > >
        > > self.__class__. FOO = value
        > >
        > > will set class-variables inside a method. Just if you wondered.
        > >
        > > Diez[/color][/color]

        Comment

        • Fredrik Lundh

          #5
          Re: direct initialization of class attributes vs. declarations w/in__init__

          digitalorganics @gmail.com wrote:
          [color=blue]
          > At first, I thought that self.jerk was resolving to the class attribute
          > instead of creating a new variable (w/ a differing scope).[/color]

          When you access an instance attribute, Python first looks in the
          instance object, and then in the class object.

          When you assign to an instance attribute, it's *always* assigned to the
          instance object, whether there's a class attribute with the same name or
          not.

          If there's already a class attribute with the same name, that attribute
          will be shadowed (but can still be accessed via the class object, of
          course).
          [color=blue]
          > It doesn't work this way on my laptop...[/color]

          Python's always worked that way, so I find that a bit hard to believe.

          </F>

          Comment

          • digitalorganics@gmail.com

            #6
            Re: direct initialization of class attributes vs. declarations w/in __init__


            Fredrik Lundh wrote:[color=blue]
            > digitalorganics @gmail.com wrote:
            >[color=green]
            > > At first, I thought that self.jerk was resolving to the class attribute
            > > instead of creating a new variable (w/ a differing scope).[/color]
            >
            > When you access an instance attribute, Python first looks in the
            > instance object, and then in the class object.
            >
            > When you assign to an instance attribute, it's *always* assigned to the
            > instance object, whether there's a class attribute with the same name or
            > not.
            >
            > If there's already a class attribute with the same name, that attribute
            > will be shadowed (but can still be accessed via the class object, of
            > course).
            >[color=green]
            > > It doesn't work this way on my laptop...[/color]
            >
            > Python's always worked that way, so I find that a bit hard to believe.
            >[/color]

            No need to be obnoxious. I do appreciate your efforts to help, but you
            must admit, your last statement is a bit snide and certainly not
            useful. I'm telling you that the code runs differently on my laptop.
            Why this is, I don't know any more /or/ less than you do apparently.
            Now, it is of course possible that I'm interpreting the results
            incorrectly, but that doesn't change the fact that I'm getting
            different results per computer with identical code.

            Comment

            • digitalorganics@gmail.com

              #7
              Re: direct initialization of class attributes vs. declarations w/in __init__

              Thank you Dennis, this makes the behavior so much clearer to me. I see
              now that when self.jerk = self.jerk + 1 is executed that even though
              the names are identical, at this point I'm referring to two different
              values (one which is being created in part from the other).

              As for my laptop, I'm not really sure what's up there. I can change the
              class variable self.jerk all I want but it has no influence over the
              instance variable. Here's the code:

              class Boo:
              jerk = 10

              def killjerk(self):
              self.jerk += 1
              print self.jerk
              print self.__class__. jerk

              bing = Boo()
              bing.killjerk()

              On my desktop, I get:

              11
              10

              On my laptop, I get:

              1
              10

              Now, if I remove the class variable, I get an AttributeError, as you'd
              expect. This happens on both the desktop and laptop. However, on the
              laptop it seems not to care what value I give the class variable jerk,
              it only requires that it exist. Any clue what's behind this behavior?
              I'm running the same python version on both computers (the ActiveState
              distro).

              Thanks for all the help...


              Dennis Lee Bieber wrote:[color=blue]
              > On 11 Jun 2006 10:35:14 -0700, digitalorganics @gmail.com declaimed the
              > following in comp.lang.pytho n:
              >[color=green]
              > > Wait a minute! It doesn't explain my bugs. I've got "class variables"
              > > acting like instance variables. What's weirder is that this behavior
              > > occurs on my computer (in both of my installed WinXP copies) but not on
              > > my laptop (WinXP Pro).
              > >[/color]
              > Don't know about the laptop but...
              >[color=green]
              > > See the following test:
              > >[/color]
              > See the following modified version:
              >
              > -=-=-=-=-=-=-
              > class Boo:
              > jerk = "yes"
              >
              > def killjerk(self):
              > print id(self.jerk), id(self.__class __.jerk)
              > self.jerk = self.jerk + "no"
              > print self.jerk, id(self.jerk)
              > print self.__class__. jerk
              >
              > bing = Boo()
              > bing.killjerk()
              > bing.killjerk()
              > -=-=-=-=-=-=-=-
              > 10837696 10837696
              > yesno 18264128
              > yes
              > 18264128 10837696
              > yesnono 18289600
              > yes
              >
              > The initial lookup for "self.jerk" does not find it in the instance,
              > so it looks higher, into the class.
              >
              > THEN when you "assign" the result to "self.jerk" you create an
              > instance specific name entry, which is bound to a string at a different
              > location. The lookup on the left side does not go outside of the
              > instance. Notice how the second "bing.killjerk( )" results in "self.jerk"
              > being bound to a third address.
              >
              > --
              > Wulfraed Dennis Lee Bieber KD6MOG
              > wlfraed@ix.netc om.com wulfraed@bestia ria.com
              > HTTP://wlfraed.home.netcom.com/
              > (Bestiaria Support Staff: web-asst@bestiaria. com)
              > HTTP://www.bestiaria.com/[/color]

              Comment

              • Fredrik Lundh

                #8
                Re: direct initialization of class attributes vs. declarations w/in__init__

                digitalorganics @gmail.com wrote:
                [color=blue]
                > Any clue what's behind this behavior?[/color]

                a missing plus sign.

                </F>

                Comment

                • Fredrik Lundh

                  #9
                  Re: direct initialization of class attributes vs. declarations w/in__init__

                  Fredrik Lundh wrote:
                  [color=blue]
                  > a missing plus sign.[/color]

                  or a misplaced one... (=+ 1 is not the same thing as += 1)

                  </F>

                  Comment

                  • digitalorganics@gmail.com

                    #10
                    Re: direct initialization of class attributes vs. declarations w/in __init__


                    Fredrik Lundh wrote:[color=blue]
                    > digitalorganics @gmail.com wrote:
                    >[color=green]
                    > > Any clue what's behind this behavior?[/color]
                    >
                    > a missing plus sign.
                    >
                    > </F>[/color]

                    Thanks for the guess but not possible given the following:

                    class Boo:
                    jerk = 10

                    def killjerk(self):
                    counter = 3
                    while counter !=0:
                    counter -= 1
                    self.jerk += 1
                    print self.jerk
                    print self.__class__. jerk


                    bing = Boo()
                    bing.killjerk()

                    Output from desktop comp.:
                    11
                    10
                    12
                    10
                    13
                    10

                    Output from laptop comp.:

                    1
                    10
                    2
                    10
                    3
                    10

                    ?? . . .

                    Comment

                    • Diez B. Roggisch

                      #11
                      Re: direct initialization of class attributes vs. declarations w/in__init__

                      > No need to be obnoxious. I do appreciate your efforts to help, but you[color=blue]
                      > must admit, your last statement is a bit snide and certainly not
                      > useful.
                      > I'm telling you that the code runs differently on my laptop.[/color]

                      It certainly doesn't. There is absolutely no imaginable way how this
                      behavior could be different, even if the python versions would differ
                      considerably. Apart from quantum-fluctuations. Or other SciFi voodoo.
                      [color=blue]
                      > Why this is, I don't know any more /or/ less than you do apparently.[/color]

                      Frederik (as one of the most profiled python developers out there) might
                      not be the most amicable of posters, but he certainly is not wrong when
                      it comes to the most basic parts of python's semantics.
                      [color=blue]
                      > Now, it is of course possible that I'm interpreting the results
                      > incorrectly, but that doesn't change the fact that I'm getting
                      > different results per computer with identical code.[/color]

                      It is NOT identical code, otherwise you won't see different
                      results. It might be code from which you _believe_ it is identical, and
                      the difference might be subtle to see. But if you'd store it in a file,
                      execute on your laptop, use an usb-stick and then transfer it to
                      whatever the other machine of yours is, it will yield the exact same
                      results.

                      Diez

                      Comment

                      • Fredrik Lundh

                        #12
                        Re: direct initialization of class attributes vs. declarations w/in__init__

                        digitalorganics @gmail.com wrote:
                        [color=blue]
                        > Output from laptop comp.:
                        >
                        > 1
                        > 10
                        > 2
                        > 10
                        > 3
                        > 10[/color]

                        so how are you entering and running the code on your laptop ?

                        what happens if you set the class attribute to 100 instead of 10 ?

                        </F>

                        Comment

                        • digitalorganics@gmail.com

                          #13
                          Re: direct initialization of class attributes vs. declarations w/in __init__

                          Oh wow, I wasn't expecting so much help. I really appreciate it. My
                          problem, however, has been solved. I uninstalled my ActiveState Python
                          distro on my laptop and installed the distro from python.org along with
                          Stan's Python Editor. I ran the same code I'd run before and guess
                          what? The behavior now matches that of my desktop! Why? *shrug*

                          As for the code being identical, it certainly was as I emailed the .py
                          file to myself (from the laptop) and downloaded it to my desktop where
                          I then ran it just as I had done on the laptop, with PythonWin. Unless
                          Google programmed Gmail to muck w/ people's python code....
                          Additionally, the bytes on the files match. Thus, I feel I can
                          guarantee that the code is indeed identical.

                          Here's my wild guess: for some reason a bug in PythonWin was causing my
                          changes to the class attribute (i.e. jerk variable) not to be reflected
                          in the actual code. This explanation, if you can call it one, still
                          doesn't make sense to me however because I could make other changes to
                          the code and it would indeed be reflected in execution. Add to the fact
                          that PythonWin is essentially just a text editor, I don't see how/why
                          it would selectively save code changes.

                          It is true that I never restarted the PythonWin IDE after a change of
                          the class attribute to something other than 0, and perhaps reinstalling
                          python etc. was unnecessary. I'm only coming to this realization now.

                          In any event, I am now problem free and quite pleased to be able to
                          exchange .py files between computers and know they'll behave the same
                          (rather, I'm assuming this henceforth).

                          Furthermore, I'd like to thank everyone who tried to help, and that
                          certainly includes Fredrik.


                          Cheers,

                          DigiO

                          Comment

                          • digitalorganics@gmail.com

                            #14
                            Re: direct initialization of class attributes vs. declarations w/in __init__


                            Fredrik Lundh wrote:[color=blue]
                            > digitalorganics @gmail.com wrote:
                            >[color=green]
                            > > Output from laptop comp.:
                            > >
                            > > 1
                            > > 10
                            > > 2
                            > > 10
                            > > 3
                            > > 10[/color]
                            >
                            > so how are you entering and running the code on your laptop ?
                            >
                            > what happens if you set the class attribute to 100 instead of 10 ?
                            >
                            > </F>[/color]

                            You can see my other post which I just sent but, I was using PythonWin:

                            1. type code in editor
                            2. hit run
                            3. observe output in interactive window

                            Comment

                            • digitalorganics@gmail.com

                              #15
                              Re: direct initialization of class attributes vs. declarations w/in __init__


                              Diez B. Roggisch wrote:[color=blue][color=green]
                              > > No need to be obnoxious. I do appreciate your efforts to help, but you
                              > > must admit, your last statement is a bit snide and certainly not
                              > > useful.
                              > > I'm telling you that the code runs differently on my laptop.[/color]
                              >
                              > It certainly doesn't. There is absolutely no imaginable way how this
                              > behavior could be different, even if the python versions would differ
                              > considerably. Apart from quantum-fluctuations. Or other SciFi voodoo.[/color]

                              Hmmm
                              [color=blue]
                              >[color=green]
                              > > Why this is, I don't know any more /or/ less than you do apparently.[/color]
                              >
                              > Frederik (as one of the most profiled python developers out there) might
                              > not be the most amicable of posters,[/color]

                              Although he dropped what I perceived to be a snide and unhelpful
                              comment, two things. One, I understand what's behind it in the sense
                              that the behavior I was describing goes against the semantic
                              fundamentals of python, and should therefore be impossible. Two,
                              Fredrik is no doubt a sweetheart and he showed it by continuing to put
                              his efforts toward helping me despite my criticism of him. I can't
                              thank him enough. Honestly, I believe newsgroups need more people like
                              him . . .

                              [color=blue]
                              > ...
                              >
                              > It is NOT identical code, otherwise you won't see different
                              > results. It might be code from which you _believe_ it is identical, and
                              > the difference might be subtle to see. But if you'd store it in a file,
                              > execute on your laptop, use an usb-stick and then transfer it to
                              > whatever the other machine of yours is, it will yield the exact same
                              > results.
                              >
                              > Diez[/color]

                              Read my other post. The code was/is definitely identical. In any event,
                              I don't really care. It's working properly now, and if I have similarly
                              weird problems in future, I'll deal with them at that time. I don't
                              know what was up, but I understand it doesn't make sense from any
                              visible standpoint of logic. Thank you for your efforts Diez...

                              Comment

                              Working...