La diferencia fundamental es que los atributos de clase son compartidos por todas las instancias de esa clase, mientras que los atributos de instancia son particulares para cada objeto creado con esa clase. Por tanto, las variables de instancia son para datos únicos y propios para cada objeto y las variables de clase son para atributos que deban ser compartidos por todas las instancias de esa clase.
Los atributos de instancia son creados usando la sintaxis instance.attr o self.attr (self es realmente una convención, simplemente es un identificador que hace referencia a la propia instancia). Como se ha dicho son locales para esa instancia y por tanto solo accesibles desde una de ellas.
Los atributos de clase se definen fuera de cualquier método de la clase, normalmente justo debajo de la cadena de documentación. Se pueden referenciar directamente desde la clase y también se puede hacer referencia a ellas desde cualquier instancia de la clase. Usos comunes son crear una constante enumerada, como variable de control en un Singleton, para establecer valores predeterminados para variables de instancia, definir constantes, etc.