В чем суть self?
Если кратко и по простому, то дело обстоит так:
Обычно класс создают для того, чтобы потом создать некоторое количество экземпляров этого класса.
При написании класса нужно как-то указать, что какие-то манипуляции нужно производить именно над конкретными экземплярами, а не над самим классом.
Для этого в функциях (кроме некоторых исключений) первым аргументом пишут имя (по традиции это как раз слово "self", хотя на самом деле там можно указать любое корректное имя). В результате, когда в функции интерпретатор видит имя self, он понимает, что речь идёт именно об одном конкретном объекте класса.
Пример:class A:
  
  # У класса есть атрибут "x"
  x = 1
  
  def change_one(self, value):
    # Эта функция меняет атрибут "x" только у того экземпляра класса,
    # для которого она вызвана
    self.x = value
  
  def change_all(self, value):
    # Эта функция меняет атрибут "x" у самого класса
    # Изменение отразится на всех экземплярах, у которых нет своего атрибута "x"
    A.x = value


a1 = A()
a2 = A()
a3 = A()

print(a1.x, a2.x, a3.x)
# Выведет: 1 1 1
# На самом деле, у экземпляров пока нет своего атрибута "x",
# но они получают его значение из класса

a1.change_one(5)

print(a1.x, a2.x, a3.x)
# Выведет: 5 1 1
# Теперь у а1 есть свой атрибут x, потому что функция change_one через self
# создала его только для того экземпляра, для которого её вызвали
# a2 и a3 по прежнему не имеют своего атрибута "x" и получают его значение из класса

a2.change_all(2)

print(a1.x, a2.x, a3.x)
# Выведет: 5 2 2
# Изменился атрибут класса, и поэтому значение изменилось для всех элементов,
# которые не имеют своего атрибута "x", а вынуждены брать его из класса

a1.change_all(7)

print(a1.x, a2.x, a3.x)
# Выведет: 5 7 7
# Совершенно всё равно, из какого экземпляра вы запускаете change_all.
# В этой функции не используется self (в отличие от change_one),
# а значит результат её вызова никак не связан с конкретным экземпляром
Гвидо где-то утверждал, что это просто соглашение, которое ничего не значит. Но это вроде указателя на экземпляр класса (как this в c++). Просто во всех методах он идет первым аргументом.