Igor, essa é uma discussão quase filosófica.
Entre as linguagens populares geralmente as coisas não são escritas em pedra.
O encapsulamento é uma boa prática mas não algo forçado.
Eu não sei se e quando o curso que está fazendo tratará desse assunto, mas no python uma prática comum é criar as propriedades com o decorador @property e ajustar o método de escrita, um examplo do stack.
O que está declarado aqui:
1) Uma classe (C) que é um modelo para criação de objetos.
2) Um métido init_ que vai ser executado sempre que criar um objeto que instancie essa classe.
3) uma propriedade x (marcado com o @property) que existirá para todos os objetos 'derivados' da classe C.
4) Dois métodos, um de escrita e outro de 'deleção' da propriedade.
Note que dessa forma sempre que você tentar alterar a propriedade na verdade você estará chamando por debaixo dos panos o método 'setter', isso permite por exemplo que você ajuste outras variáveis internas ou faça algum outro procedimento (gravar em um banco de dados talvez?), que garantirá o encapsulamento do objeto.
No entanto você não é obrigado a fazer dessa forma... Se você declarar apenas uma 'variável' interna na classe, você poderá modificá-la diretamente, mesmo sem ter escrito um método setter.
Talvez o seu curso vá tratar desses aspectos posteriormente.
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
print("getter of x called")
return self._x
@x.setter
def x(self, value):
print("setter of x called")
self._x = value
@x.deleter
def x(self):
print("deleter of x called")
del self._x
c = C()
c.x = 'foo' # setter called
foo = c.x # getter called
del c.x # deleter called