views:

1685

answers:

5

I'm coming from the JAVA world and reading bruce eckels' python 3 patterns idioms.

While reading about classes...it goes on to say that in python there is no need to declare class variables. You just use them in the constructor...and boom..they are there.

So for example:

class Simple:
        def __init__(self1, str):
                print("inside the simple constructor")
                self1.s = str
        def show(self1):
                print(self1.s)
        def showMsg (self, msg):
                print (msg + ':', self.show())

My question is, if above is the case 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?

+1  A: 

Python has limited support for private identifiers, through a feature that automatically prepends the class name to any identifiers starting with two underscores. This is transparent to the programmer, for the most part, but the net effect is that any variables named this way can be used as private variables.

See here for more on that.

In general, Python's implementation of object orientation is a bit primitive compared to other languages. But I enjoy this, actually. It's a very conceptually simple implementation and fits well with the dynamic style of the language.

Dan Olson
+15  A: 

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 pretense 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.

Just Some Guy
+1 for emphasizing culture
hasen j
That makes sense. However, I dont think there is any way in java to access private variables outside the class (except actually changing the source of the class ofcourse). Is there?
Omnipresent
Interesting, I come from a PHP background and I'm wondering how this works in practice. Isn't it dangerous for classes to be able to modify what would be private members if the language used was something other than Python?
David Caunt
Not that I know of, but the point is that you *can* edit the source, or even the compiled bytecode. Nothing can stop you if you're determined enough to mess around with that class's innards. So why expend the effort to prevent it, instead of relying on convention and thin mechanisms to say "don't do that!" And when it comes down to it, no matter how bad of an idea it may usually be, sometimes you really *do* want to fiddle around where you're not supposed to.
Just Some Guy
@David - the presumption is that we're all adults here. Don't break things that you can't fix! In this case, that means that you shouldn't mess around with those private members like __foo or _bar. Again, in practice, that's just not done without an extremely good reason. It might not be theoretically pure, but I've never once seen a real-world situation where it was a problem.
Just Some Guy
+1: We're all adults. The "private" and "protected" keywords are interesting comments, but so is a leading `_` on the variable name. Python is distributed -- and run -- as source. There's no '.class' file to conceal the implementation behind.
S.Lott
I tend to prefer the python way, but I don't think the java way is as pointless as you make out. Declaring something private quickly tells someone reading the code something very useful: this field is only ever modified inside this class.
Ned
So does __foo in Python, and _bar means that you can but probably shouldn't.
Just Some Guy
+5  A: 

"In java, we have been taught about public/private/protected variables"

"Why is that not required in python?"

For the same reason it's not required in Java.

You're free to use -- or not use private and protected.

As a Python and Java programmer, I've found that private and protected are very, very important design concepts. But as a practical matter, in tens of thousands of lines of Java and Python, I've never actually used private or protected.

Why not?

Here's my question "protected from whom?"

Other programmers on my team? They have the source. What does protected mean when they can change it?

Other programmers on other teams? They work for the same company. They can -- with a phone call -- get the source.

Clients? It's work-for-hire programming (generally). The clients (generally) own the code.

So, who -- precisely -- am I protecting it from?

Right. The schizophrenic sociopath who refused to read the API comment blocks.

S.Lott
+1 very well said. should have just added 'python gives you wings'
Omnipresent
@Omnipresent: I don't know about wings, but I do know that -- because of Java -- I don't make much use of duck typing. If I did, I might be even more productive in Python. I find that a good inheritance hierarchy (one that would translate to Java) is usually worth the effort in Python.
S.Lott
+1: best analysis of the concept ever.
Stefano Borini
The very question "protected from whom?" simply shows you don't understand what this is about. It's not about security. It's about making it easy for your IDE to know which methods are part of the public interface, and making it easy for your compiler to show that nobody is accidentally using anything else, which together make it easier for *you*, the programmer, to reason about your program.
Porculus
@Porculus: "making it easy for your IDE to know"... What? My IDE is an editor. I'm the designer. I know what the design is about. My IDE is an editor and knows nothing. Who is the mysterious "nobody" who "accidentally using anything else"? Specifically? Who is the person? Why aren't they informed of the right way to use the API?
S.Lott
-1: I agree with Porculus. It's not about forbidding access or hiding something, it's about *implicit* API documentation. Developers as well as compilers/interpreter/code-checker easily see which members are recommended to be used and which ones shouldn't get touched (or at least with care). In most cases it would be a horrible mess if all members of a class or module were public. Consider the distinction of private/protected/public members as a service, saying: "Hey, these members are important while those are used internally and probably not useful for you."
Oben Sonne
@Oben Sonne: "Implicit API documentation"? What? Do you mean letting people guess what your intent is? How can anyone guess? The public/private/protected seems very poor compared with actual documentation written to support an actual programmer's use cases.
S.Lott
@S.Lott: I agree that API docs have higher priority and often are the only way to communicate intended uses of an API. But sometimes member names and visibility (in terms of private/public) sufficiently speak on their own. Also, I see your point that the idea of implicit documentation does not work well in editors w/o API inspection but it is really helpful in IDE's with code completion. Assuming you've read the API docs already some time ago it helps you to remember how to use a class. Things wouldn't work that smart if there were no distinction between private and public members.
Oben Sonne
@Oben Sonne: "Things wouldn't work that smart if there were no distinction between private and public members"? Things? What things? "IDE's with code completion"? Is that the thing which wouldn't work smart? Please read http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620. Public/private/protected conflate too many things to be actually useful. The API documentation often conveys more -- and more useful -- information that `private`. `private` is simply too little information to be of any real value.
S.Lott
A: 

My method is to use 512 bit variable name generate by Whirlpool and a random number generator. When variables names look like this "_P_3CCF8252D8BBB258460D9AA999C06EE38E67CB546CFFCF48E91F700F6FC7C183AC8CC3D3096DD30A35B01F4620A1E3A20D79CD5168544D9E1B7CDF49970E87F1". And this variable names change from one release version to another by automated script. It will not actually prevent or make the variables privat but it will make life difficult for anyone not using the provided API.

That's pretty close to what "__foo" does. :-)
Just Some Guy
A: 

Python does not need to protect anyone from assigning a value to a member variable, because: A) In Python you cannot accidentally make a typo such that a comparison turns into an assignment. B) Python developers do not make mistakes. C) All of the above. D) What was the question again?

Johnny