2016-07-16 3 views
2

Python использует соглашение подчеркивания для частных переменных. Однако, ничто не кажется, чтобы остановить вас от портя базового класса случайно, напримерКак избежать случайного испорчения базового класса в Python?

class Derived(Base): 
    def __init__(self, ...): 
     ... 
     super(Derived, self).__init__(...) 
     ... 
     self._x = ... 

если Base также случается использовать имя _x.

Каковы наилучшие методы предотвращения такого рода ошибок?

Это кажется особенно сложным, если разные люди реализованы Base и Derived классов, или _x был добавлен в Base после Derived были реализованы (Таким образом, реализация Derived будет нарушение инкапсуляции задним числом)

ответ

4

Использование private variables with two underscores. Таким образом, имя mangling защищает вас от испортить ваш родительский класс (в нормальных случаях использования).

Поскольку есть действительный вариант использования для членов класса и частного (а именно, чтобы избежать конфликтов имен имен с именами, определенными подклассами), существует ограниченная поддержка такого механизма, называется имя коверкание. Любой идентификатор формы __spam (по крайней мере два ведущих символа подчеркивания, не более одного нижнего подчеркивания) заменяется текстовым символом _classname__spam, где classname - это текущее имя класса с разделительными подчеркиваниями. Это манипулирование выполняется независимо от синтаксического положения идентификатора, если оно встречается в определении класса.

[...] Обратите внимание, что правила манипуляции разработаны в основном для предотвращения несчастных случаев; все еще можно получить доступ или изменить переменную, которая считается частной. Это может быть даже полезно в особых обстоятельствах, например, в отладчике.

Пример

class A(object): 
    def __init__(self): 
     self.__v = 1 
    def __str__(self): 
     return "A = {}".format(self.__v) 

class B(A): 
    def __init__(self): 
     A.__init__(self) 
     self.__v = 2 
    def __str__(self): 
     return "{}; B = {}".format(A.__str__(self), self.__v) 

a = A() 
b = B() 
print(a) 
print(b) 

дает

A = 1 
A = 1; B = 2 
+1

Насколько я знаю, вы можете получить доступ к переменным, используя их подогнанных имен, так что это не надежен, как говорят, приватная переменная в Java. – paisanco

+1

В отношении документации на python: * Обратите внимание, что правила манипуляции разработаны в основном для предотвращения несчастных случаев; все еще можно получить доступ или изменить переменную, которая считается частной. Это может быть даже полезно в особых обстоятельствах, например, в отладчике. * Я добавлю это к своему ответу. – mhoff