Christopher Brookes wrote:
Hi,
Is there in Python private/protected attributes in class like in other
langage ?


There's a short answer, a long answer, and an even longer answer.

The short answer is No.

The long answer is, not exactly. Python has private names, but they are not enforced by the compiler, but only by naming convention: use names starting with a single underscore to mean "private":

_private_variable = 42

Anybody using such private names will know that they have nobody to blame but themselves if things break.

Inside classes (but not outside), there is a second convention which is enforced by the compiler: name mangling. If you define this:

class K:
    _a = 23
    __b = 42  # TWO leading underscores


the _a attribute is private by convention, but the __b attribute has its name mangled by the compiler to:

    _K__b


This is to prevent *accidental* clashes when writing subclasses, but of course it can't prevent deliberate access. Since you know the name of the class, it's easy to do your own mangling and get access to the "private" attribute.

(For extra bonus points, can you see which circumstances namespace mangling will fail to prevent accidental name clashes?)


You might be thinking that double-underscore names are "stronger", and therefore safer, than single-underscore. No. In my opinion, don't waste your time and energy with double-underscore names.

There's one further naming convention that is relevant: names with double leading and trailing underscores. These names are reserved for Python, and are used for special methods like __init__ __getitem__ __enter__ etc.


The even longer answer is, no, and thank goodness for that, because having the compiler enforce private attributes is a real pain! It gets in the way of testing and debugging, and testing is MUCH more important than private or protected.

It does very little good, and lots of harm, and gets in the way of things that you need. The internet is full of people asking "how do I access private members" and similar questions. They're not asking it to be difficult, but because they need to. It is a *good* thing that Python makes it a convention.

In every language that I know of, it is possible to bypass the compiler's protection of private and protected attributes:

E.g. in Ruby:
http://blog.confabulus.com/2008/10/26/testing-protected-and-private-methods-in-ruby/
http://www.skorks.com/2010/04/ruby-access-control-are-private-and-protected-methods-only-a-guideline/

In C++:
http://www.gotw.ca/gotw/076.htm
http://stackoverflow.com/questions/729363/is-it-possible-to-access-private-members-of-a-class

Java:
http://stackoverflow.com/questions/1306166/how-can-i-access-private-class-members-in-java


Python takes another approach. Instead of putting up barriers to the caller that must be overcome, barriers that just get in the way of debugging and testing, Python doesn't waste it's time trying to enforce something that people will find a way to break. Instead Python takes the attitude "we're all adults here". It trusts you not to access private attributes and methods unless you really need to, and to take the consequences if you do.

(The only exception is that protection of objects written in C is treated more strongly, because that could cause a core dump and potential memory corruption, not just a safe Python exception. But even there, using the new ctypes module, you can do some pretty scary things.)



--
Steven

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to