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.
d.kinddoesn't assign to the class variable. It assigns to an instance variable. The fact that there is also akindclass variable doesn't matter.d.kind = ...creates an instance variable called kind. What you really need to do is changeDog.kind = .... When you referenced.kind(outside of assignment) then it checks the local scope ofddoesn't find it so checks forDog.kindand finds it.