Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Python have “private” variables in classes?

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?

like image 751
Omnipresent Avatar asked Oct 29 '09 01:10

Omnipresent


People also ask

Are variables in classes private?

This is possible with a combination of private rather than public class variables, and methods that can be called to find out what these variable values are. Class variables that are declared as private can not be referred to from other classes, they are only visible within their own class.

Can you access private variables within a class?

We can access a private variable in a different class by putting that variable with in a Public method and calling that method from another class by creating object of that class.

Are Python class variables public?

All the variables and the methods in the code are public by default.


2 Answers

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. Python mangles the names of variables like __foo so that they're not easily visible to code outside the class 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 stay away even if you're not technically prevented from doing so. You don't play around with another class's variables that look like __foo or _bar.

like image 54
Kirk Strauser Avatar answered Sep 16 '22 14:09

Kirk Strauser


Private variables in python is more or less a hack: the interpreter intentionally renames the variable.

class A:     def __init__(self):         self.__var = 123     def printVar(self):         print self.__var 

Now, if you try to access __var outside the class definition, it will fail:

>>> x = A() >>> x.__var # this will return error: "A has no attribute __var"  >>> x.printVar() # this gives back 123 

But you can easily get away with this:

>>> x.__dict__ # this will show everything that is contained in object x                # which in this case is something like {'_A__var' : 123}  >>> x._A__var = 456 # you now know the masked name of private variables >>> x.printVar() # this gives back 456 

You probably know that methods in OOP are invoked like this: x.printVar() => A.printVar(x), if A.printVar() can access some field in x, this field can also be accessed outside A.printVar()...after all, functions are created for reusability, there is no special power given to the statements inside.

The game is different when there is a compiler involved (privacy is a compiler level concept). It know about class definition with access control modifiers so it can error out if the rules are not being followed at compile time

like image 20
watashiSHUN Avatar answered Sep 20 '22 14:09

watashiSHUN