[Tutor] Object, methods, class
Steven D'Aprano
steve at pearwood.info
Sun Feb 27 00:31:58 CET 2011
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
More information about the Tutor
mailing list