Как получить доступ к `обычным` закрытым переменным в python?

У меня есть модуль Python, M1.

# m1.py
class C1(object):
    def __init__(self):
        self.__pri = 10
        self._pro = 5
        self.pub = 1

Тогда в bpython,

>>> import m1
>>> c = m1.C1()
>>> c.__pri
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'C1' object has no attribute '__pri'
>>> c._pro
5
>>> c.pub
1
>>> dir(c)
['_C1__pri', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_pro', 'pub']
>>> c._C1__pri
10

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

редактировать: я ожидал получить доступ к c.__pri прямо, но оказывается, что name mangling мешает мне сделать это, как ответили ниже. Спасибо всем!

3 ответа

Решение

Двойное подчеркивание меняет имя класса с атрибутом, начинающимся с одного подчеркивания

    c._C1__pri

разрешает доступ к атрибуту. Вроде псевдо-приватности, но у него есть и другое применение. Я не уверен, что вы ожидали с c.__private, Я думаю, что ты хотел сделать c.__pri хотя результат был бы таким же.

__pri Атрибут не является закрытым, потому что к нему можно получить доступ за пределами класса, для этого требуется всего несколько символов.

как упомянуто ниже в jadkik94, это не делает невозможным доступ, а сигнализирует другому программисту, что он не должен использовать атрибут.

К вашему сведению, в другой раз это может пригодиться при использовании наследования

class Parent: 
    def __method(self): 
        print 'Parent method'

class Child(Parent): 
    def __method(self): 
        print 'Child method'

>>> c = Child()
>>> c._Child__method()
Child method
>>> c._Parent__method()
Parent method

двойное подчеркивание предотвращает случайное переопределение имени (не то, что это наблюдается очень часто).

То, что вы наблюдаете, это искажение имени, в котором имя переменной с двумя ведущими подчеркиваниями и не более чем одним последним подчеркиванием переименовывается, чтобы предотвратить случайные столкновения с подклассами и предотвратить случайное хакерское изменение личного поля.

Тем не менее, довольно легко определить, как называется переменная после искажения, так что это не помешает определенному патологическому пользователю.

Имя Мэнлинг

Это обеспечивает метод для объявления закрытого члена класса.

Такое двойное подчеркивание имен помогает предотвратить перезапись внутренней закрытой переменной в подклассах.

Типичный способ показать, что переменная-член не должна использоваться, состоит в том, чтобы завершить ее одним подчеркиванием, хотя это всего лишь соглашение.

Другие вопросы по тегам