Question
I'm coming from the Java world and reading Bruce Eckels' Python 3 Patterns, Recipes and Idioms.
While reading about classes, it goes on to say that in Python there is no need to declare instance variables. You just use them in the constructor, and boom, they are there.
So for example:
class Simple:
def __init__(self, s):
print("inside the simple constructor")
self.s = s
def show(self):
print(self.s)
def showMsg(self, msg):
print(msg + ':', self.show())
If that’s true, then any object of class Simple
can just change the value of
variable s
outside of the class.
For example:
if __name__ == "__main__":
x = Simple("constructor argument")
x.s = "test15" # this changes the value
x.show()
x.showMsg("A message")
In Java, we have been taught about public/private/protected variables. Those keywords make sense because at times you want variables in a class to which no one outside the class has access to.
Why is that not required in Python?
Answer
It's cultural. In Python, you don't write to other classes' instance or class variables. In Java, nothing prevents you from doing the same if you really want to - after all, you can always edit the source of the class itself to achieve the same effect. Python drops that pretence of security and encourages programmers to be responsible. In practice, this works very nicely.
If you want to emulate private variables for some reason, you can always use
the __
prefix from [PEP 8](https://www.python.org/dev/peps/pep-0008/#method-
names-and-instance-variables). Python mangles the names of variables like
__foo
so that they're not easily visible to code outside the namespace that
contains them (although you can get around it if you're determined enough,
just like you can get around Java's protections if you work at it).
By the same convention, the _
prefix means _variable
should be used
internally in the class (or module) only, even if you're not technically
prevented from accessing it from somewhere else. You don't play around with
another class's variables that look like __foo
or _bar
.