Search code examples
pythonmetaprogramming

use of access modifier like underscore in python module control how variable defined or module, function, class imported should be accessed?


Python doesn't have any mechanism that effectively restricts access to any instance variable or method. Python prescribes a convention of prefixing the name of the variable/method with single or double underscore to emulate the behaviour of protected and private access specifiers.

class Employee(object):
    def __init__(self, name, sal):
        self._name=name  # protected attribute 
        self._salary=sal # protected attribute

while this mechanism is used in Object Oriented programming , my question is can we use this approach to convey other developers that how I want the access of a variable or an imported module in my python module.

In a company I worked long back we had a practice to use _ with a variable or an import if we want to tell the developers that I do not want this variable or module I imported here to be access from outside this module.

if it is the way to tell how I want to define the access of variable or a module or function or class I import from elsewhere into my module. Is it documented somewhere ? (like in ieee.org)

**some_module.py**

from some_module_api import preset as _preset

.
.
.

Solution

  • Quoting the Python Style Guide PEP8:

    In addition, the following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention):

    _single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose names start with an underscore.

    single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g.

    tkinter.Toplevel(master, class_='ClassName')

    __double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).

    __double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.

    You should follow these conventions as otherwise you can both confuse other coders, or write code subject to break in the future (like inventing double underscored "magic" names).

    As for imported names into your code, respect the hints from other coders, unless you have strong reasons not to. When defining aliases from imported names with as, the same rules apply to the aliases that are now names in your own module.