4
def __f():
  print 1

def _f():
  print 1

I tried import and it's accessible:

>>> import test1
>>> test1._f()
1

Does it mean anything? I want to write some helper functions which aren't class-based. Then I want to hide certain low-level, concrete functions, and leaving only high-level function (view them as APIs) accessible to users to use.

For example:

test1.copy() will call another helper function in the same file which does some extra checking, but I don't want to expose that to user.

CppLearner
  • 16,273
  • 32
  • 108
  • 163
  • possible duplicate of [Private functions / Variables enforcement in python](http://stackoverflow.com/questions/5559256/private-functions-variables-enforcement-in-python) – Francis Avila Apr 23 '12 at 06:09

4 Answers4

11

The single leading underscore is a Python naming convention. A number of tools rely on that convention. For example help() will ignore single underscored names. Using from somemodule import * will also ignore single underscored names.

The double leading underscore triggers name mangling (prefixing the name with the class name and a single leading underscore). It is used to create thread-local references. That allows intra-class calls that won't be accidentally broken by a subclass. There is a nice example of this in the tutorial at http://docs.python.org/tutorial/classes.html#private-variables .

Lastly, there is the special method naming convention of two leading underscores and two trailing underscores. Those names are used by the interpreter to implement operators and to implement a number of standard protocols (i.e. iterators, context managers, pickling, etc). See http://www.rafekettler.com/magicmethods.html for a nice write-up on the special methods.

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
3

The leading underscore convention is just that - a convention respected by polite programmers.

A leading underscore is a hint to other programmers that _function() is an internal implementation detail and shouldn't be used externally. There's nothing stopping them from calling _function() - but by doing so they're ignoring your hint that the implementation of _function() could change at any time. If something breaks, they get to keep both pieces.

The Python interpreter does not enforce any kind of restriction.

Li-aung Yip
  • 12,320
  • 5
  • 34
  • 49
2

Well, it's a fairly established nomenclature convention, which ain't nothing. Also, it affects from [module] import *, which only imports functions not prefixed with underscores.

zmccord
  • 2,398
  • 1
  • 18
  • 14
2

If I recall correctly there actually was not a clean way to make any function private in python. The language is not intended to work this way. The underscore notation is just a common protocol among the developers, to denote something which probably is private or hidden.

There however might be a way to simulate private functionality. The first thing which pops in my head is using traceback module and then inspect a calling instance, to see if it matches the expected. This by no way is something what I would do in my projects, and I would strongly advise against this, but if you absolutely cant live without it, that might be a way to go.

jbreicis
  • 588
  • 2
  • 8
  • Thank you very much. It's been a long time reading my introductory book. Nice review, I guess :) – CppLearner Apr 23 '12 at 06:12
  • You can do horrible things like monkey-patching the `__call__()` method, and so forth. Let's **not** talk about that... *shudders* – Li-aung Yip Apr 23 '12 at 06:14
  • It could also use a hand-rolled module (subclass module and override `__getattribute__` to check for access rights... But yeah, don't do it :) – TryPyPy Apr 23 '12 at 06:24