Why Are Python'S 'Private' Methods Not Actually Private

Why are Python's 'private' methods not actually private?

The name scrambling is used to ensure that subclasses don't accidentally override the private methods and attributes of their superclasses. It's not designed to prevent deliberate access from outside.

For example:

>>> class Foo(object):
... def __init__(self):
... self.__baz = 42
... def foo(self):
... print self.__baz
...
>>> class Bar(Foo):
... def __init__(self):
... super(Bar, self).__init__()
... self.__baz = 21
... def bar(self):
... print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}

Of course, it breaks down if two different classes have the same name.

Private methods in Python

Python doesn't have the concept of private methods or attributes. It's all about how you implement your class. But you can use pseudo-private variables (name mangling); any variable preceded by __(two underscores) becomes a pseudo-private variable.

From the documentation:

Since there is a valid use-case for class-private members (namely to
avoid name clashes of names with names defined by subclasses), there
is limited support for such a mechanism, called name mangling. Any
identifier of the form __spam (at least two leading underscores, at
most one trailing underscore) is textually replaced with
_classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard
to the syntactic position of the identifier, as long as it occurs
within the definition of a class.

class A:
def __private(self):
pass

So __private now actually becomes _A__private.

Example of a static method:

>>> class A:
... @staticmethod # Not required in Python 3.x
... def __private():
... print 'hello'
...
>>> A._A__private()
hello

Is it bad practice NOT to use private methods and functions in Python?

From technical point of view, there is no right or wrong way of writing code. What computer cares about are instructions and data. If you use clases or not, if your code is modular or spaghetti, what are the names of your functions, if they are public or private etc. - it all goes down the drain by the time it reaches the CPU.

Arguments like these are arguments about opinions. Everybody has an opinion. You might also call it taste. People with similar opinions group together and create organizations, political parties, institutions etc. to promote their ideas. They claim that it is somehow possible to generalize and distill how software should be written, into decisions that are either "right" or "wrong".

Yet, for every rule that proves something, you will quickly find another rule that contradicts it. This is just the law of nature - reality knows no boundaries. This is the reason of all confusion.

There is no such thing as universal rule about something, and there never will be. It would contradict the very nature of the universe: time and entropy. Whatever question you ask, the answer is always "it depends".

After 40 years of programming my core values are down to this:

  • Consistency matters more than style.
  • Make it easy for the reader to understand what you are doing, and even more importantly, why.
  • A good comment in the right place can save a week of headaches.
  • The reader might be you.
  • Always try to choose the best tool for the job.
  • Follow conventions where they make sense, but do not hesitate to break the rules when you have a justified reason for it.
  • Nobody knows better what makes sense than the person writing the code. Keep asking yourself: Does the thing that I'm doing make sense, or do I see a better way?
  • Less is more.

Why are some methods with __ in front of them not private?

A double leading underscore does not actually make a method private. A single leading underscore hints that the method should be for internal use only, but is not enforced by python.

__init__

has a double leading and trailing underscore which means that it is a magic method that is reserved for special use by python. You should never name a method with double leading and trailing underscores.

python private and public methods, what are they used for?

Private methods are intended for use by only your own class and not to be called anywhere else. The purpose it serves is encapsulation.

Making a method private in a python subclass

Python is distributed as source. The very idea of a private method makes very little sense.

The programmer who wants to extend B, frustrated by a privacy issue, looks at the source for B, copies and pastes the source code for method into the subclass C.

What have you gained through "privacy"? The best you can hope for is to frustrate your potential customers into copying and pasting.

At worst, they discard your package because they can't extend it.

And yes, all open source is extended in one way or another. You can't foresee everything and every use to which you code will be put. Preventing some future use is hard to do when the code is distributed as source.

See How do I protect Python code?


Edit On "idiot-proof" code.

First, python is distributed as source 90% of the time. So, any idiot who downloads, installs, and then refuses to read the API guide and calls the methods out of order still has the source to figure out what went wrong.

We have three classes of idiots.

  • People who refuse to read the API guide (or skim it and ignore the relevant parts) and call the methods out of order in spite of the documentation. You can try to make something private, but it won't help because they'll do something else wrong -- and complain about it. [I won't name names, but I've worked with folks who seem to spend a lot of time calling the API's improperly. Also, you'll see questions like this on SO.]

    You can only help them with a working code sample they can cut and paste.

  • People who are confused by API's and call the methods every different way you can imagine (and some you can't.) You can try to make something private, but they'll never get the API.

    You can only help them by providing the working code sample; even then, they'll cut and paste it incorrectly.

  • People who reject your API and want to rewrite it to make it "idiot proof".

    You can provide them a working code sample, but they don't like your API and will insist on rewriting it. They'll tell you that your API is crazy and they've improved on it.

    You can engage these folks in an escalating arms race of "idiot-proofing". Everything you put together they take apart.

At this point, what has privacy done for you? Some people will refuse to understand it; some people are confused by it; and some people want to work around it.

How about public, and let the folks you're calling "idiots" learn from your code?

Private functions / Variables enforcement in python

No. And that's the philosophy of python: Do not make the compiler/parser enforce privacy since developers who want to access private members have ways to do so anyway (reflection etc.).
The idea is telling people Hey, this is not part of the public API. If you use it improperly, it could breaks things or kill your cat. I might also change the signature often since it's not part of the public API and I don't have to care about people using it

And fyi, you can actually access double-underscore variables (same applies for methods) from outside using obj._ClassName__variableName. Besides that it's not encouraged to use double underscores except for mixin objects - you can never know if someone wants to subclass your class.

Does python support private variables?

There is a lot of literature on this topic, but in short:

Python is different to programming languages that have actually "private" attributes in that no attribute can be truly inaccessible by other functions. Yes, we can simulate the behaviour of languages like Java using property, as you've shown, but that is kind of fudging "true" private attributes. What property actually is is a higher-order function (well, technically, it's a decorator), so when you call c.x, although it acts as a property, you're really referring to a function that controls whether you can use the getters and setters defined in it.

But just because c.x doesn't allow direct read access, doesn't mean that you can't call print c._x (as @avigil pointed out). So c._x isn't really private - it's just as easily accessible as any other attribute belonging to the C class. The fact that its name starts with an underscore is just a convention - a signal to fellow programmers: "Please don't handle this variable directly, and use the getters/setters instead" (if available).

call a private method in an imported class

A function with a name starting with 2 underscore characters is not intented to be called from outside its class. And in order to allow users to redefine it in a subclass with each class calling its one (not the normal method override), its name is mangled to _className__methodName.

So here, you really should not use it directly, but if you really need to, you should be able to do:

fc._FirstClass__function2()

Why private methods in the object oriented?

Lot of good answers, but maybe one more from a self-taught Java programmer as I went through all that by myself with a lot of pain ;)

Think about a Class as something seen from the outside, not as something you see internally. If you look at a Class from the outside, what you see?

Taking the clock as an example again, a clock can give you info about the current time and it can be set up to show the right time.

So looking at things from the outside, a clock is a machine that can do those two things; public methods we call them.

But we as constructors of this clock we know that before any time operation we have to switch from 23 to 11 on our display (it's that kind of clock), so we have to rearrange things internally a bit to do so. Changing from 23 to 11 works just fine for us in both cases - setting the clock and showing the current time - but we do it "on the side" as the user doesn't have to know about all that complicated math. These are private methods!

So our Clock Class could have two public methods (showTime and setTime) which are all that the user wants to see, and a private method (recountTime) that provides functionality for these public methods and are something that the user doesn't want to see.

So on the one hand, you should keep in mind that private is what won't be reimplemented and accessed by future programmers using your code (as was pointed at in the answers above). But private also means things done on the side, so the user don't see it. That's why we call the public methods a public interface - it's all the user will see from the outside.

For me it is helpful (I'm self-taught, so maybe it's not a very popular methodology...) to write down everything the users (real users and other Classes) will do with my Class (public interface with just public methods' signatures), then to write the signatures of private methods that I-the-implementer will use to accomplish the public goals that promised to provide to my users and then just fulfill it with code.

It can be helpful to keep in mind that the old C rule is still valid (as was expressed in 97 Things Every Programmer Should Know): a function/method should be just a few lines long, really!!



Related Topics



Leave a reply



Submit