Skip to main content
deleted 4 characters in body
Source Link
NotAnAmbiTurner
  • 2.8k
  • 3
  • 25
  • 47

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <moudule_name><module_name> syntax (see Ben Wilhelm's answer)
Simply

Simply remove one underscore from the a.__numa.__num of the question's example and it won't show in modules that import a.py using the from a import * syntax.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such

Such a variable has its name "mangled" to include the classname etc.
It

It can still be accessed outside of the class logic, through the mangled name.
Although

Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <moudule_name> syntax (see Ben Wilhelm's answer)
Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py using the from a import * syntax.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name "mangled" to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <module_name> syntax (see Ben Wilhelm's answer)

Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py using the from a import * syntax.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)

Such a variable has its name "mangled" to include the classname etc.

It can still be accessed outside of the class logic, through the mangled name.

Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 
minor addition to improve clarity, based on the author's statements himself
Source Link

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <moudule_name> syntax (see Ben Wilhelm's answer)
Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py using the from a import * syntax.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name "mangled" to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <moudule_name> syntax (see Ben Wilhelm's answer)
Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name "mangled" to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <moudule_name> syntax (see Ben Wilhelm's answer)
Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py using the from a import * syntax.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name "mangled" to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 
Corrected statement about module privates (these do get imported with some forms of the import syntax)
Source Link
mjv
  • 75.7k
  • 14
  • 119
  • 158

There may be confusion between class privates and module privates.

A module private beginsmodule private starts with a singleone underscore
Such a element is not copied along when using the from <module_name> import * form of the import. command; it is however imported if using the import <moudule_name> syntax (see Ben Wilhelm's answer)
Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py.

A class private beginsclass private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name "mangled" to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 

There may be confusion between class privates and module privates.

A module private begins with a single underscore
Such a element is not copied along when using import.
Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py.

A class private begins with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name "mangled" to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <moudule_name> syntax (see Ben Wilhelm's answer)
Simply remove one underscore from the a.__num of the question's example and it won't show in modules that import a.py.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name "mangled" to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli's funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 
added 196 characters in body
Source Link
mjv
  • 75.7k
  • 14
  • 119
  • 158
Loading
added 124 characters in body; edited body
Source Link
mjv
  • 75.7k
  • 14
  • 119
  • 158
Loading
added 232 characters in body
Source Link
mjv
  • 75.7k
  • 14
  • 119
  • 158
Loading
added 789 characters in body; added 44 characters in body
Source Link
mjv
  • 75.7k
  • 14
  • 119
  • 158
Loading
Source Link
mjv
  • 75.7k
  • 14
  • 119
  • 158
Loading