Python — это объектно-ориентированный язык с самого начала его разработки, и первым элементом объектно-ориентированного мышления является инкапсуляция. Так называемая инкапсуляция, вообще говоря, это атрибуты и методы в классе, которые делятся на публичные и приватные. самое важное понятие в инкапсуляции — контроль доступа.
Существует три уровня контроля доступа: частный, защищенный, публичный.
Частный: только сам класс может получить доступ Protected (Защищено): доступ может получить только сам класс и подклассы Публичный (Public): любой класс может получить доступ
Поскольку Python не похож на Java, в нем есть символы управления доступом (private/public/protected), так что контроль доступа Python также легко игнорировать и ошибаться кандидатам.
Публичный (Общественный)
В классах Python атрибуты, определенные по умолчанию, являются общедоступными.
class Foo(object):
bar = 123
def __init__(self, bob):
self.bob = bob
print(Foo.bar) # 123
foo = Foo(456)
print(foo.bob) # 456
выше классFooсерединаbarАтрибуты — это атрибуты класса,__init__Боб, определенный в методе, является атрибутом экземпляра,barиbobВсе свойства являются общедоступными, доступ к которым возможен извне, соответственно, в классе печатиbarи в случаеbob, выводится соответствующее значение.
Защищено
Чтобы определить защищенный атрибут в Python, просто добавьте подчеркивание перед его именем._, мы помещаем метод Foo вbobиbarизменить на_bobи_bar, они становятся защищенными свойствами, код выглядит следующим образом:
class Foo(object):
_bar = 123
def __init__(self, bob):
self._bob = bob
class Son(Foo):
def print_bob(self):
print(self._bob)
@classmethod
def print_bar(cls):
print(cls._bar)
Son.print_bar() # 123
son = Son(456)
son.print_bob() # 456
определить классSonунаследовано отFoo, так как доступ к защищенному объекту возможен только внутри класса и в подклассах, он не может быть вызван напрямуюprint(Son._bar)илиprint(son._bob)для вывода значений этих двух свойств, поэтому определитеprint_barиprint_bobметод, реализация выводится в подклассе, и этот код тоже выводится нормально_barи_bobзначение .
Затем попробуйте обратно проверить, что вы можете получить доступ к его свойствам вне класса, и измените выходную часть приведенного выше кода следующим образом:
print(Son._bar) # 123
son = Son(456)
print(son._bob) # 456
(Притвориться) С удивлением обнаружил, что ошибки нет и выводится правильное значение.
Использование символов подчеркивания для определения защищенных переменных в Python — это согласованная спецификация, а не уровень языка, который фактически реализует контроль доступа, поэтому к определяемым нами защищенным переменным по-прежнему можно получить доступ извне (это функция, а не ошибка).
частный
Python определяет частные атрибуты, вам нужно добавить два символа подчеркивания перед именем атрибута.__, измените приведенный выше код и запустите его, вы обнаружите, что любая печать в следующем коде будет сообщать об ошибке.
class Foo(object):
__bar = 123
def __init__(self, bob):
self.__bob = bob
class Son(Foo):
def print_bob(self):
print(self.__bob) # Error
@classmethod
def print_bar(cls):
print(cls.__bar) # Error
print(Son.__bar) # Error
son = Son(456)
print(son._bob) # Error
Копните глубже — действительно ли частная собственность недоступна?
Чтобы понять, действительно ли частные свойства недоступны, нужно начать с того, как Python реализует частные свойства. В CPython атрибут двойного подчеркивания становится_ClassName__PropertyNameВ виде кода для демонстрации:
class Foo(object):
__bar = 123
print(Foo._Foo__bar) # 123
Запустите его, чтобы узнать, что вывод нормальный__bar, но не рекомендуется обращаться к закрытым свойствам таким образом, потому что разные интерпретаторы Python обрабатывают частные свойства по-разному.
особый случай
Используйте двойные символы подчеркивания для определения закрытых атрибутов.Есть особый случай.Когда после атрибута есть два символа подчеркивания, этот атрибут будет рассматриваться интерпретатором Python как магический метод, поэтому он не будет рассматриваться как частный.
class Foo(object):
__bar__ = 123
print(Foo.__bar__) # 123
Приведенный выше код выводит 123, что доказывает, что интерпретатор Python не__bar__как частная собственность. При определении частных свойств важно помнить, что имя может иметь только одно подчеркивание в конце.
еще один частный случай
Если заданное имя атрибута вызывается__Шерстяная ткань? Просто попробуйте:
class Foo(object):
__ = 123
print(Foo.__) # 123
имя можно найти__свойства не считаются частными свойствами, равно как и свойства, имена которых содержат несколько символов подчеркивания (например,_______).
контроль доступа к функциям
Управление доступом к атрибутам в основном было представлено выше. В Python функции являются гражданами первого класса. Так называемые граждане первого класса означают, что функции могут использоваться как переменные, поэтому к управлению доступом к функциям и атрибутам применяются те же правила, что и к выше.