Basic Class/Instance Question

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

    Basic Class/Instance Question

    Ready to go insane here. Class A, taking on a default value for a
    variable. Instantiating two separate objects of A() gives me a shared
    val list object. Just see the example bellow:


    class A(object):
    def __init__(self, val=[]):
    self.val=val

    obj1 = A()
    obj2 = A()

    print obj1 is obj2 # False - as expected
    print obj1.val is obj2.val # True! - Why... oh god WHY


    -----------
    Using python 2.4. Is this a bug with this version of python? How can I
    trust the rest of the universe is still in place? Could she still like
    me? Many questions I have. Lets start with the python problem for now.

    Thanks,
    Sia

  • Alan Franzoni

    #2
    Re: Basic Class/Instance Question

    Il 23 May 2007 04:07:19 -0700, Siah ha scritto:
    Ready to go insane here. Class A, taking on a default value for a
    __init__ is a function, taking a default value of [], which is a list,
    which is a mutable object. That said, you should remember that this means
    that such default value is 'shared' between all instances. If you don't
    want that, do something like:

    def __init__(self, defaultvalue=No ne):
    if defaultvalue is None:
    defaultvalue=[]




    --
    Alan Franzoni <alan.franzoni. xyz@gmail.com>
    -
    Togli .xyz dalla mia email per contattarmi.
    Remove .xyz from my address in order to contact me.
    -
    GPG Key Fingerprint (Key ID = FE068F3E):
    5C77 9DC3 BD5B 3A28 E7BC 921A 0255 42AA FE06 8F3E

    Comment

    • Bruno Desthuilliers

      #3
      Re: Basic Class/Instance Question

      Siah a écrit :
      Ready to go insane here. Class A, taking on a default value for a
      variable. Instantiating two separate objects of A() gives me a shared
      val list object. Just see the example bellow:
      >
      >
      class A(object):
      def __init__(self, val=[]):
      self.val=val
      >
      obj1 = A()
      obj2 = A()
      >
      print obj1 is obj2 # False - as expected
      print obj1.val is obj2.val # True! - Why... oh god WHY
      >
      >
      -----------
      Using python 2.4. Is this a bug with this version of python? How can I
      trust the rest of the universe is still in place? Could she still like
      me? Many questions I have. Lets start with the python problem for now.
      This is a FAQ. Default arguments are only evaled once - when the def
      statement is evaled (which is usually at import time). The solution is
      simple: don't use mutable objects as default arguments:

      class A(object):
      def __init__(self, val=None):
      if val is None:
      val = []
      self.val=val

      FWIW, do you really believe such a 'bug' would have stayed unnoticed ?-)

      Else, the rest of the universe seems to be in place, and I don't know if
      she'll still like you if she learn you didn't read the FAQ before
      posting !-)

      HTH

      Comment

      • Antoon Pardon

        #4
        Re: Basic Class/Instance Question

        On 2007-05-23, Bruno Desthuilliers <bruno.42.desth uilliers@wtf.we bsiteburo.oops. comwrote:
        Siah a écrit :
        >Ready to go insane here. Class A, taking on a default value for a
        >variable. Instantiating two separate objects of A() gives me a shared
        >val list object. Just see the example bellow:
        >>
        >>
        >class A(object):
        > def __init__(self, val=[]):
        > self.val=val
        >>
        >obj1 = A()
        >obj2 = A()
        >>
        >print obj1 is obj2 # False - as expected
        >print obj1.val is obj2.val # True! - Why... oh god WHY

        >>
        >-----------
        >Using python 2.4. Is this a bug with this version of python? How can I
        >trust the rest of the universe is still in place? Could she still like
        >me? Many questions I have. Lets start with the python problem for now.
        >
        This is a FAQ. Default arguments are only evaled once - when the def
        statement is evaled (which is usually at import time). The solution is
        simple: don't use mutable objects as default arguments:
        An immutable object would have given the same behaviour in this case

        class A(object):
        def __init__(self, val = ()):
        self.val=val

        obj1 = A()
        obj2 = A()

        print obj1 is obj2 # False
        print obj1.val is obj2.val # True

        Comment

        • Wildemar Wildenburger

          #5
          Re: Basic Class/Instance Question

          Antoon Pardon wrote:
          >This is a FAQ. Default arguments are only evaled once - when the def
          >statement is evaled (which is usually at import time). The solution is
          >simple: don't use mutable objects as default arguments:
          >>
          >
          An immutable object would have given the same behaviour in this case
          >
          class A(object):
          def __init__(self, val = ()):
          self.val=val
          >
          obj1 = A()
          obj2 = A()
          >
          print obj1 is obj2 # False
          print obj1.val is obj2.val # True
          >
          >
          Yeah, but is that a problem? Since you can not change them anyway,
          there's no harm.
          W

          Comment

          • Antoon Pardon

            #6
            Re: Basic Class/Instance Question

            On 2007-05-23, Wildemar Wildenburger <wildemar@freak mail.dewrote:
            Antoon Pardon wrote:
            >>This is a FAQ. Default arguments are only evaled once - when the def
            >>statement is evaled (which is usually at import time). The solution is
            >>simple: don't use mutable objects as default arguments:
            >>>
            >>
            >An immutable object would have given the same behaviour in this case
            >>
            >class A(object):
            > def __init__(self, val = ()):
            > self.val=val
            >>
            >obj1 = A()
            >obj2 = A()
            >>
            >print obj1 is obj2 # False
            >print obj1.val is obj2.val # True
            >>
            >>
            Yeah, but is that a problem? Since you can not change them anyway,
            there's no harm.
            I think it can make comprehension harder if you suggest in your
            explanation that a partcilular behaviour is linked to an object
            being mutable while that has nothing to do with it.

            You are correct that one can't mutate the val attribute but
            some code might depend on the distinction identical or not
            instead of equal or not. Not understanding this issue of
            default arguments could cause a bug in such code even
            if the default argument is not mutable.

            --
            Antoon Pardon

            Comment

            Working...