When I first started to learn python, I was confused about the naming conventions for the private fields. Since I have only very faint memory about it regarding JavaScript, I think it’s a good idea to compare them side to side(Well…since both languages are not as strict as Java).
Python
Python does not really have “private” fields per spec defination, but it does have some conventions to help hide the field from being accessed (you can still access them — but avoid doing that!) and prevent namespace pollution.
Several rules can be applied and adopted by the community:
Single Underscore: ._variable/method
This simply means that the variable or method should be be accessed from outside and is just for convention.
food.pyclass Food:
def __init__(self):
self.taste = "sweet"
self._weight = 500>>> t = Food()
>>> t.tast
"sweet"
>>> t._weight
500
However, it will raise error when calling from wildcard import:
_single_leading_underscore: weak “internal use” indicator. E.g.
from M import *
does not import objects whose name starts with an underscore.
Double Underscore: .__variable/method
This will make python interpreter modify the identifier to a different format to avoid accidental access and is enforced by the Python interpreter.
Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, whereclassname
is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.Name mangling is intended to give classes an easy way to define “private” instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class.
Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private.
class Food(object):
def __init__(self):
self.__taste = 'sweet'>>> t = Food()
>>> t.__taste
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Food' object has no attribute '__taste'
To access it (you have strong will!) :
>>> t._Food__taste
'sweet'
Double Underscore both sides: .__variable/method__
This means a method is reserved for python internal use like __init__
. They are often referred to as magic methods. You can actually write your own ones but try not to do that as it might cause unexpected behaviour.
Single Trailing Underscore on the right: .variable/method_
This is by convention to avoid naming conflicts with Python reserved keywords:
>>> def bread(self, class):
SyntaxError: "invalid syntax"
>>> def bread(self, class_):
... pass
Single Underscore: _
Sometimes used as a name for temporary or insignificant variables (“don’t care”). Also: The result of the last expression in a Python REPL.
>>> bread = ('bagel', 'toast', 'baguette', 'sourdough')
>>> a, _, _, d = bread
>>> a
'bagel'
>>> _
'baguette'
JavaScript:
Things are a more simplified in JavaScript. Up until now, private(protected) properties are usually prefixed with an underscore _
just like in Python and is a convention to follow but no enforcement.
So our property will be called _waterAmount
:
class Food {
_bread= 'toast'
}let food = new Food();food.bread; // Error
food._bread; //"toast"
However the good news is that in ES2019, private class fields are defined using a hash #
prefix ( TC39 stage 3: draft proposal ) and it has been implemented in Babel.
class Food {
material= 'wholemeal';
#taste = 'sweet';
static #weight = 500; bread() {
this.#taste;
}
}let food = new Food();food.bread(); // runs OK
food.#taste; // error - private property cannot be modified outside class
Hola! That’s all.
Happy Reading!