В чем разница между _b и b в этом месте - PullRequest
1 голос
/ 22 декабря 2009
class a:
    def __init__(self):
        self._b()#why here use _b,not b,What's the difference
        self._c='cccc'#why here use _c,not c,What's the difference
    def _b():
        print 'bbbb'

a.py

class a:
    def __init__(self):
        self._b()#why here use _b,not b,What's the difference
        self._c='cccc'#why here use _c,not c,What's the difference
    def _b(self):
        print 'bbbb'

b.py

from  a import *
b=a()
b._b()
print b._c

это печать BBBB BBBB BBBB BBBB сссс

Почему их можно распечатать, а не _b и _c частные переменные.

Ответы [ 7 ]

10 голосов
/ 22 декабря 2009

Префикс имени переменной или функции с подчеркиванием - это соглашение в Python, указывающее, что переменная является закрытой. От Документы :

Закрытые ”переменные экземпляра, к которым нельзя получить доступ, кроме как внутри объекта, в Python не существует. Однако существует соглашение, которому следует большая часть кода Python: имя с префиксом подчеркивания (например, _spam) следует рассматривать как непубличную часть API (будь то функция, метод или элемент данных) , Он должен рассматриваться как деталь реализации и может быть изменен без уведомления.

8 голосов
/ 22 декабря 2009

Согласно pep8 (http://www.python.org/dev/peps/pep-0008/), единственное подчеркивание предназначено для обозначения «обычно частного» метода или атрибута. Сам интерпретатор не взаимодействует с единственным подчеркиванием, это скорее соглашение. Двойное подчеркивание OTOH имеет значение в переводчике.

4 голосов
/ 22 декабря 2009

По сути, идея состоит в том, что в соглашении Python есть три уровня инкапсуляции / сокрытия.

  1. Открытые атрибуты и методы: к ним могут обращаться другие классы без ограничений.

  2. Закрытые атрибуты и методы (с префиксом подчеркивания): они предназначены для сокрытия от внешнего мира. Подчеркивание служит чем-то вроде предупреждения: вам не следует трогать этот метод, если вы действительно не знаете, что делаете. Прежде всего, это используется для разграничения между конечными пользователями (меньшими смертными) и другими разработчиками.

  3. Существует третий уровень, называемый искалеченным. Любые искаженные атрибуты / методы в основном не должны быть затронуты кем-либо, кто не является автором этого кода. Это важно для основного функционирования программы и не должно быть затронуто, потому что, если оно используется не по назначению, это может привести к нежелательному / незапланированному поведению.

В вашем случае метод _b является закрытым. Автор этого кода хочет сообщить вам, что это не предназначено для публичного использования, а если вы пишете обертку вокруг этого класса или что-то в этом роде (в основном, если вы разработчик, использующий этот класс), то вы можете использовать метод. В противном случае, лучше, если вы этого не сделаете.

Кроме того, одно подчеркивание перед переменной (или методом) связывает его с этим классом. Поэтому, когда вызывается a._b, интерпретатор ищет его в определении класса a.

3 голосов
/ 22 декабря 2009

Разница между одинарным и двойным подчеркиванием:

class Foo(object):

    def regular_method(self):
        print 'ok'

    def _soft_private(self):
        print 'ok'

    def __mangled_private(self):
        print 'ok'

f = Foo()
f.regular_method()
# prints ok
f._soft_private()
# print ok
f.__mangled_private()
# error! no such attribute. BUT:
f._Foo__mangled_private()
# prints ok

Таким образом, по сути, в python нет настоящей «конфиденциальности», но есть соглашение об использовании единственного подчеркивания, чтобы предупредить разработчика с помощью вашего API, что он делает это на свой страх и риск.

0 голосов
/ 22 декабря 2009

Объект класса a имеет атрибут _b, который обнаруживается при запросе self._b. Тот же объект класса a не имеет атрибута b.

_b и b отличаются от beehive и zulu.

Вы получите ошибку параметра при вызове self._b, поскольку Python неявно передаст self в качестве первого аргумента связанному методу. Подпись должна быть:

def _b(self):
    print('bbbb')
0 голосов
/ 22 декабря 2009

Подчеркивание просто используется для обозначения, что переменная является закрытой.

0 голосов
/ 22 декабря 2009

Вы заметите, что b нигде не определено. Пока _b есть.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...