Ключевое отличие между этими вариантами в том, что в случае участия (явного, либо предположительного) вашего класса в механизме
наследования, лучше использовать вариант
с двумя подчеркиваниями, что позволит избежать возможной нежелательной перезаписи значения атрибута в противном случае (использование публичного, либо псевдо-приватного с одинарным подчеркиванием):
>>> class A:
def __init__(self, value):
self._value = value
def meth_a(self):
print('Class A Method with value {}...'.format(self._value))
>>> class B(A):
def meth_b(self, value):
self._value = value
print('Class B Method with value {}...'.format(self._value))
>>> x = B(100)
>>> x.meth_a()
Class A Method with value 100...
>>> x.meth_b(40)
Class B Method with value 40...
>>> x.meth_a()
Class A Method with value 40... # Значение атрибута объекта класса А изменилось !
>>> class A:
def __init__(self, value):
self.__value = value
def meth_a(self):
print('Class A Method with value {}...'.format(self.__value))
>>> class B(A):
def meth_b(self, value):
self.__value = value
print('Class B Method with value {}...'.format(self.__value))
>>> x = B(100)
>>> x.meth_a()
Class A Method with value 100...
>>> x.meth_b(40)
Class B Method with value 40...
>>> x.meth_a()
Class A Method with value 100... # Значение атрибута объекта класса А осталось неизменным !
Происходит это по причине, о которой вам уже написали - обращение Python к подобным атрибутам/методам (с двумя начальными подчеркиваниями) через имя соответствующего Класса (при одинаковых явных атрибутах
self.__value в обоих классах, мы имеем на самом деле два разных:
self._A__value и
self._B__value).