It is very dangerous to have direct access to class instances for many reasons.
1- Changing the Name of an Instance Variable
The first problem with direct access is that changing the name of an
instance variable will break any client code that uses the original name directly. if the developer changes the name of an instance
variable in the class from self.originalName to self.newName, then any client software that uses the original name directly will break.
2- Changing an Instance Variable into a Calculation
A second situation where direct access is problematic is when the code of
a class needs to change to meet new requirements. Suppose that when
writing a class, you use an instance variable to represent a piece of data,
but the functionality changes so that you need an algorithm to compute a
value instead.
3- Validating Data
The third reason to avoid direct access when setting a value is that client
code can too easily set an instance variable to an invalid value. A better
approach is to call a method in the class, whose job is to set the value. As
the developer, you can include validation code in that method to ensure
that the value being set is appropriate.
So, it is always better to use getters and setters methods just in case an instance variable needs to be accessed from outside the class.
But, there are certain circumstances where it is safe to use direct access: when it is absolutely clear what the instance variable means, little or no validation of the data is needed, and there is no
chance that the name will ever change. A good example of this is the Rect
(rectangle) class in the pygame package. A rectangle in pygame is defined
using four values—x, y, width, and height—like this:
oRectangle = pygame.Rect(10, 20, 300, 300)
After creating that rectangle object, using oRectangle.x, oRectangle.y,
oRectangle.width, and oRectangle.height directly as variables seems acceptable
Source: Object-oriented python by Irv Kalb