When using class and instance variables/methods what you care is visibility!
A class variable/method is shared by all the instances of the class while the instance variable/method is only available to the instance you have right now!
Generally speaking, instance variables are for data unique to each instance and class variables are for attributes and methods shared by all instances of the class: python tutorial
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind # shared by all dogs
'canine'
>>> e.kind # shared by all dogs
'canine'
>>> d.name # unique to d
'Fido'
>>> e.name # unique to e
'Buddy'
What this example is not showing you is that with a class method you can call the method on the class without going through an instance!
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
@classmethod
def isGoodBoy(cls):
return True # all dogs are good boys!
Now the isGoodBoy
method does not need to access the name of the dog, so it can be a class method and this reflects on all instances; after all all dogs are good boys (and gals!).
But this tells you more! is a dog a good boy? Are we asking for any specific dog to be a good boy?
>> Dog.isGoodBoy() # here we call the method on the class
True # debate settled!
Now four your other questions; it's good practice to have a class method when you do work on classes, not objects. How do you know if an instance of a logger requires the network before creating it? That's what class methods and class variables are for, along with having common state and behavior for all objects of that class.
Now as this is shared between all classes you now have other problems, each instance of the class might modify the class variable! This also means that you can query the variable value without an object!
Say you want to switch from method A to method B while running.
class Foo:
upgrade = False
def a(self):
...
def b(self):
...
def run(self):
self.a() if self.upgrade else self.b()
Now a Foo.upgrade = True
will switch stuff for everybody! Or even better make a dog a feline by running Dog.kind = 'feline'