By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,183 Members | 1,321 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,183 IT Pros & Developers. It's quick & easy.

Bug or Feature with (overriding) Class Variables?

P: n/a
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?
Jul 18 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
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
Jul 18 '05 #2

P: n/a
# 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

Jul 18 '05 #3

P: n/a
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.
Jul 18 '05 #4

P: n/a
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/>
Jul 18 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.