Bug or Feature with (overriding) Class Variables?

Discussion in 'Python' started by Eric Baker, Nov 16, 2003.

  1. Eric Baker

    Eric Baker Guest

    With this little snippet, i get an inconsistency between the behavior
    of string and dictionary class variables:

    Python 2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)] on win32
    Type "copyright", "credits" or "license" for more information.
    IDLE 0.8 -- press F1 for help
    >>> class foo:

    dict = {}
    string = "foostring"
    def bar(self):
    self.dict["bar-key"] = "bar-value"
    self.string = "bar-string"



    >>> # Lets create an instance of Foo
    >>> baz = foo()
    >>> baz.dict

    {}
    >>> baz.string

    'foostring'
    >>> # No suprises yet, the class variables are shown
    >>>
    >>> # Now lets call bar() and change some vars
    >>> baz.bar()
    >>> baz.dict

    {'bar-key': 'bar-value'}
    >>> # Did it return a class variable or an instance variable?
    >>> baz.__class__.dict

    {'bar-key': 'bar-value'}
    >>> # As you can see, both show the same values
    >>>
    >>> baz.dict is baz.__class__.dict

    1
    >>> # So we see that both are actually the same instance
    >>> # of the dictionary class
    >>>
    >>> # Now we look at the string
    >>> baz.string

    'bar-string'
    >>> # Obviously this was the instance variable
    >>> baz.__class__.string

    'foostring'
    >>> # And this was the class variable
    >>> baz.string is baz.__class__.string

    0
    >>> # And we actually can see, that they are different
    >>> # instances of the string class


    Question: Which behavior is the correct one?
    Question: Is this a bug or a feature?
    Eric Baker, Nov 16, 2003
    #1
    1. Advertising

  2. Eric Baker

    Peter Otten Guest

    Eric Baker wrote:

    > With this little snippet, i get an inconsistency between the behavior
    > of string and dictionary class variables:
    >
    > Python 2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)] on win32
    > Type "copyright", "credits" or "license" for more information.
    > IDLE 0.8 -- press F1 for help
    >>>> class foo:

    > dict = {}
    > string = "foostring"
    > def bar(self):


    Here you are changing the value of foo.dict. The equivalent to the following
    line where you are rebinding the value of self.string would be:

    self.dict = {"bar-key": "bar-value}

    > self.dict["bar-key"] = "bar-value"
    > self.string = "bar-string"


    But there's a twist: when you say fooinstance.attribute, attribute ist first
    looked up in the instance, and then if not found, in the class. So
    depending on the context, fooinstance.attribute may refer to a class or an
    instance attribute. On the other hand, fooinstance.attribute = somevalue
    will always rebind the instance attribute, to rebind the class attribute
    you can do

    foo.attribute = somevalue

    or

    fooinstance.__class__.attribute = somevalue

    > Question: Which behavior is the correct one?


    Both.

    > Question: Is this a bug or a feature?


    Feature that bugs you?


    Peter
    Peter Otten, Nov 16, 2003
    #2
    1. Advertising

  3. Eric Baker

    Roel Mathys Guest

    # on python 2.3.2

    class foo (object) :
    dict = {}
    string = "foostring"
    def bar(self):
    self.dict["bar-key"] = "bar-value"
    # is the same as
    # self.dict.__setitem__( "bar-key" , "bar-value" )
    # which tries to look up self.dict
    # try:
    # self.dict2["bar-key"] = "bar-value"
    # which results in an attribute error

    self.string = "bar-string"
    # is adding an attribute string to the instance
    # foo.string remains accessible

    baz = foo()
    baz.string is foo.string => True
    baz.bar()
    baz.string is foo.string => False


    bye,
    rm
    Roel Mathys, Nov 16, 2003
    #3
  4. Eric Baker

    Eric Baker Guest

    Thank you Peter and Roel,

    I don't believe this stumped me for hours. I guess that happens if you stay
    up too late.

    Basically what it boils down to, is that the operater "=" is doing different
    things.

    With the expression:
    self.dict["bar-key"] = "bar-value"
    You are modifying an existing instance of dict.

    Wheras with this experession:
    self.string = "bar-string"
    You are actually creating a new instance, because strings are immutable the
    "=" operater does not modify the string but actually creates a new one
    within the current scope.

    self.string = "bar-string"
    is actually
    self.string = str("bar-string")

    and

    self.dict["bar-key"] = "bar-value"
    is actually
    self.dict.__setitem__("bar-key" , "bar-value" )

    Thanks for your help.
    Eric Baker, Nov 16, 2003
    #4
  5. Eric Baker

    Ben Finney Guest

    On Sun, 16 Nov 2003 11:29:19 -0500, Eric Baker wrote:
    > Basically what it boils down to, is that the operater "=" is doing
    > different things.


    No, the '=' operator is being consistent -- it always assigns a new
    value to whatever is on the lhs (left-hand side).

    What is inconsistent is the lhs object you are assigning to.

    > With the expression:
    > self.dict["bar-key"] = "bar-value"


    Because you're not putting the dict itself on the lhs; you're referring
    to one of its indexed values.

    If, instead, you put:

    self.dict = { "foo": "bar-value" }

    this *would* be an equivalent operation to:

    self.string = "bar-value"

    > Wheras with this experession:
    > self.string = "bar-string"
    > You are actually creating a new instance, because strings are
    > immutable the "=" operater does not modify the string but actually
    > creates a new one within the current scope.


    As would happen if you did the same thing to a dict.

    --
    \ "If you get invited to your first orgy, don't just show up |
    `\ nude. That's a common mistake. You have to let nudity |
    _o__) 'happen.'" -- Jack Handey |
    Ben Finney <http://bignose.squidly.org/>
    Ben Finney, Nov 16, 2003
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Yakov

    Java overriding bug?

    Yakov, Sep 5, 2004, in forum: Java
    Replies:
    13
    Views:
    666
    Mike Schilling
    Sep 9, 2004
  2. Nicodemus
    Replies:
    0
    Views:
    285
    Nicodemus
    Jul 17, 2003
  3. Corey Lubin
    Replies:
    8
    Views:
    371
    Hung Jung Lu
    Nov 18, 2003
  4. looping
    Replies:
    38
    Views:
    858
    Bengt Richter
    Apr 25, 2006
  5. robic0
    Replies:
    7
    Views:
    103
    Samwyse
    Jan 24, 2006
Loading...

Share This Page