Bug or Feature with (overriding) Class Variables?

E

Eric Baker

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 dict = {}
string = "foostring"
def bar(self):
self.dict["bar-key"] = "bar-value"
self.string = "bar-string"



Question: Which behavior is the correct one?
Question: Is this a bug or a feature?
 
P

Peter Otten

Eric said:
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 helpdict = {}
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
 
R

Roel Mathys

# 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
 
E

Eric Baker

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.
 
B

Ben Finney

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top