Si il est important pour l'intégrité (i.e. le bon fonctionnement) de l'objet d'éviter une modif de variables internes, oui, ça paraît une bonne idée d'expliciter cette contrainte pour le client par la sémantique du programme.
S'il s'agit d'une limitations du design, renforcer le côté limitation par la sémantique est plutôt une bonne idée (du moins, c'est ce que mon expérience me dit).
L'autre solution, c'est de le dire dans la doc.
Mais personne ne lit vraiment la doc.
Et même si on la lisait, ça serait très irritant de lire des trucs du style si vous appelez cette fonction, alors surtout après ne touchez pas à cet attribut, hein, svp merci.
(D'autant qu'on est en Python, si c'est pour lire des trucs comme ça, on ferait du PHP)
Bien sûr, de base c'est un attribut, le client est pas sensé y toucher.
Mais il y a une différence entre la POO me dit que je viole l'encapsulation et l'auteur du code n'a pas prévu de gérer mes conneries.
Sur le long terme, ça peut payer : l'interface plantera, plutôt que laisser le dev qui débute essayer de comprendre pourquoi ce qu'il fait est nul.
Au besoin, il comprendra bien vite que la doc peut l'aider, et il corrigera son erreur.
Pour le dev expérimenté, c'est pas hyper gênant : il va pouvoir passer au travers. Il sera en hors-piste ; il fait ce qu'il veut, mais la direction décline toute responsabilité en cas d'avalanche.
Enfin, si vraiment t'as pas envie de générer les property à la main, ça reste automatisable.