0

I need help in writing code that does what I think it should do.

Here's the code:

class Food:
    kind = 'fruit'
    def __init__(self, name):
        self.name = name

a = Food('tomato')
b = Food('cabbage')

print 'a ->', a.kind
print 'b ->', b.kind
print 'change a\'s kind'
a.kind = 'veg'
print 'a ->', a.kind
print 'b ->',b.kind
print 'change kind in the class'
Food.kind = 'meat'
print 'a ->', a.kind
print 'b ->', b.kind

The output I got was this:

a -> fruit
b -> fruit
change a's kind
a -> veg
b -> fruit
change kind in the class
a -> veg
b -> meat

It's the last result that puzzles me. If I've declared 'kind' correctly as a class attribute then surely when I change it in the class with 'Food.kind = ' it should change it for both instance. Actually I expected it to change when I gave it the new value via one of the instances also, but it only changed it in one. What am I missing here?

2
  • 1
    Check the next link: toptal.com/python/… . It explains how class attributes and instance attributes work in Python. Commented Sep 30, 2014 at 21:46
  • Until you assign a.kind = 'veg', the kind attribute doesn't exist on the instance, and is references the class variable. If you want it to repoint back at the class variable, then del a.kind and you will get meat for both again. Commented Sep 30, 2014 at 21:53

2 Answers 2

1

Attribute lookup starts from instance's dictionary, so changing kind in class won't affect* a's kind attribute. But other instances of the class that still don't have that attribute will still look for it in class dictionary or further up in in the class tree if not found in Food.

>>> a.kind = 'veg'
>>> a.__dict__
{'kind': 'veg', 'name': 'tomato'}
>>> b.__dict__
{'name': 'cabbage'}

Since, there are no base classes here attribute lookup will stop immediately after Food for non-existent attributes resulting in AttributeError.

>>> a.foo

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    a.foo
AttributeError: Food instance has no attribute 'foo'

Note that in new-style classes special methods are always looked up in class not instances. But since you're using an old-style class(removed in Python 3) that won't be the case. But it is recommended to always use new-style classes(i.e inherit from object in Python 2).

You should read: New-style and classic classes.


* Mutable class attributes(lists, dict etc) are one exception here, doing in-place operations on them from either instance or class will be reflected everywhere in class and other instances(unless an instance defined a new attribute by the same name):

class Food:
    kind = []
    def __init__(self, name):
        self.name = name

a = Food('tomato')
b = Food('cabbage')
b.kind = []
a.kind.append(10)
Food.kind.append(20)
print a.kind #[10, 20]
print b.kind #[]  b.kind points to a different object due to the assignment above
print Food.kind #[10, 20]
Sign up to request clarification or add additional context in comments.

Comments

0

You may be aware that in C++/Java referencing a static member via an instance is frowned upon. Instead you are encouraged to refer to static members via a class reference In Java, for instance:

theThing.value = 1; // bad
Thing.value = 1; // good

In Python, when reading a field on an instance, Python will first look at the instance's fields. If no instance field is found then the instance's class's fields will be inspected.

When writing to a field, the field written is always the object that was referenced -- be that an instance or a class. For instance:

theThing.value = 1 # creates an instance field if one does not exist
Thing.value = 1 # creates a class field if one does not exist

Thus, when reading the value of kind: a.kind will always read the instance field (unless the field is deleted); and b.kind will always read the class field (unless an instance field is created).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.