1

In working through the python tutorial on classes, it describes class and instance variables. My question is this: In the example below, why does 'kind' behave like an instance variable even though it is declared (at least by its position as a class variable?

I followed the tutorial example and defined the dog class as

class Dog:
    kind = 'canine'         # class variable shared by all instances
    tricks = []

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

I then created two instances and printed out the variables

d = Dog('Fido')
e = Dog('Buddy')
print('After initialize instances:     {!s:<8}{!s:<10}{!s:<}'.format(d.name, d.kind, d.tricks))
print('After initialize instances:     {!s:<8}{!s:<10}{!s:<}\n'.format(e.name, e.kind, e.tricks))

and recieved the expected output.

After initialize instances:     Fido    canine    []
After initialize instances:     Buddy   canine    []

I then append to fido tricks with

d.tricks.append('roll over')

and got the expected output from similar print statements:

After append roll over to Fido: Fido    canine    ['roll over']
After append roll over to Fido: Buddy   canine    ['roll over']

I understand why Buddy also has 'roll over.' The tricks are a class variable. What I don't understand is I then set fido.kind to cat with

d.kind = 'cat'

Which only changes the value for the instance 'd.' Simular print statements give:

After set Fido kind to cat:     Fido    cat       ['roll over']
After set Fido kind to cat:     Buddy   canine    ['roll over']

Why is the type of the instance 'e' or Buddy still canine?

Finally, I set the tricks to a list rather than appending, and it only changed the result returned by 'd' or 'Fido.' In other words after:

d.tricks = ['play dead', 'roll over']

Similar print statements give:

After set Fido tricks to list:  Fido    cat       ['play dead', 'roll over']
After set Fido tricks to list:  Buddy   canine    ['roll over']

I know similar questions are here, here and here (to name a few). But I still don't get it. I think my misunderstanding has something to do with mutable objects and when the idenity is set. If someone could help me that would be great.

Also, I wonder 'Is 'kind' really a class variable?' Also, Can I / Should I define instance variables not in the class methods but just under the class definition as 'kind' is in this example?

Sorry for the long question.

Community
  • 1
  • 1
  • Assigning to `d.kind` doesn't assign to the class variable. It assigns to an instance variable. The fact that there is also a `kind` class variable doesn't matter. – user2357112 Oct 28 '16 at 02:08
  • as @user2357112 points out `d.kind = ...` creates an instance variable called kind. What you really need to do is change `Dog.kind = ...`. When you reference `d.kind` (outside of assignment) then it checks the local scope of `d` doesn't find it so checks for `Dog.kind` and finds it. – AChampion Oct 28 '16 at 02:09
  • Thanks! So, in python, you can add a new variable to an instance after the instance is created. I didn't know that. A 'print(Dog.kind)' does always give 'canine.' – Will Holmes Oct 28 '16 at 02:43

0 Answers0