Почему «частные» методы Python на самом деле не являются частными?

Python дает нам возможность создавать «частные» методы и переменные внутри класса, добавляя двойные подчеркивания к имени, например: __myPrivateMethod(). Как же тогда это объяснить?

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!

В чем дело?!

Я объясню это немного для тех, кто не совсем понял.

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()

Что я там сделал, так это создал класс с общедоступным методом и частным методом и создал его экземпляр.

Затем я вызываю его общедоступный метод.

>>> obj.myPublicMethod()
public method

Затем я пытаюсь вызвать его частный метод.

>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'

Здесь все выглядит хорошо; мы не можем это назвать. На самом деле это «личное». На самом деле это не так. Запуск dir () на объекте открывает новый магический метод, который python волшебным образом создает для всех ваших «частных» методов.

>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']

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

>>> obj._MyClass__myPrivateMethod()
this is private!!

Так много для инкапсуляции, а?

В любом случае, я всегда слышал, что Python не поддерживает инкапсуляцию, так зачем даже пытаться? Что дает?


person willurd    schedule 16.09.2008    source источник
comment
То же самое верно для Java или C #, если вы используете отражение (что каким-то образом вы там делаете).   -  person 0x434D53    schedule 22.02.2015
comment
Он был создан для целей модульного тестирования, поэтому вы можете использовать этот хак для модульного тестирования частных методов вашего класса извне.   -  person waas1919    schedule 12.04.2016
comment
Разве тестирование частных методов не является антипаттерном? Частные методы наверняка будут использоваться в некоторых общедоступных методах, иначе они просто не будут использоваться навсегда. И правильный способ тестирования частных методов (основанный на моих знаниях, полученных в ходе работы над ThoughtWorks) состоит в том, что вы пишете тесты только для общедоступных методов, которые охватывают все случаи. Если это работает нормально, вам вообще не нужно тестировать частные методы извне.   -  person Vishnu Narang    schedule 23.01.2017
comment
@VishnuNarang: Да, это то, чему часто учат. Но, как всегда, почти религиозный подход: всегда делать это, никогда не делать этого - единственное, что никогда не бывает хорошо. Если модульные тесты используются только для регрессионных тестов или тестирования общедоступного API, вам не нужно тестировать частные. Но если вы занимаетесь разработкой, управляемой модульными тестами, есть веские причины для тестирования приватных методов во время разработки (например, когда сложно имитировать определенные необычные / экстремальные параметры через общедоступный интерфейс). Некоторые языки / среды модульного тестирования не позволяют вам этого делать, что, IMHO, не очень хорошо.   -  person Marco Freudenberger    schedule 13.02.2017
comment
@MarcoFreudenberger Я понимаю вашу точку зрения. У меня есть опыт разработки, основанной на модульных тестах. Часто, когда становится сложно имитировать параметры, чаще всего это решается изменением и улучшением дизайна. Я еще не встречал сценария, в котором дизайн был бы идеальным, и все же модульное тестирование чрезвычайно сложно избежать тестирования частных методов. Я буду следить за такими случаями. Спасибо. Я был бы признателен, если бы вы могли поделиться одним сценарием из головы, чтобы помочь мне понять.   -  person Vishnu Narang    schedule 13.02.2017
comment
У меня нет подходящего сценария, который бы прямо или косвенно не задействовал внешнее оборудование (например, я много работаю над системами машинного зрения, для определенных значений, передаваемых частным методам, необходимо создать определенные изображения, которые может быть сложно - потому что общедоступный интерфейс будет принимать изображения с камеры или из набора тестовых изображений в случае модульных тестов).   -  person Marco Freudenberger    schedule 14.02.2017
comment
Действительно хорошая идея, что мы все согласны со взрослыми. Факт: в группе достаточно программистов, как и в любой другой группе, мудрость распространяется неравномерно. Если бы все знали все, stackoverflow не существовало бы. Вот еще одна цитата: я пришел ради философии, а ушел ради реальности.   -  person omni    schedule 23.05.2018
comment
@masi Плюс, если вы больше, чем простейшая кодовая обезьяна, вам придется совмещать в уме несколько вещей во время программирования. Чистые кодировщики делают методы небольшими, чтобы не помнить слишком много вещей. Если мне нужно подражать типобезопасности в голове, это еще одна вещь, которая отвлекает от сосредоточения внимания на архитектуре и алгоритмах.   -  person Raphael Schmitz    schedule 20.02.2019
comment
Разоблачая частные методы, питон, похоже, предпочитает «печень, свисающая из грудной клетки», хотя ему и предлагают «мы все взрослые, в Python мы доверяем».   -  person Espresso    schedule 19.07.2019
comment
Это возможно (иш). См. Мой ответ ниже: stackoverflow.com/a/64985332/2419960   -  person Moradnejad    schedule 31.05.2021


Ответы (13)


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

Например:

>>> class Foo(object):
...     def __init__(self):
...         self.__baz = 42
...     def foo(self):
...         print self.__baz
...     
>>> class Bar(Foo):
...     def __init__(self):
...         super(Bar, self).__init__()
...         self.__baz = 21
...     def bar(self):
...         print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}

Конечно, он не работает, если два разных класса имеют одинаковое имя.

person Alya    schedule 16.09.2008
comment
docs.python.org/2/tutorial/classes.html. Раздел: 9.6 о частных переменных и локальных ссылках на классы. - person gjain; 17.10.2013
comment
Для тех из нас, кому лень прокручивать / искать: Прямая ссылка на Раздел 9.6 - person cod3monk3y; 20.02.2014
comment
Красиво - причина положительная! Я читал / слышал, что это было просто для предотвращения преднамеренного доступа извне (без фактического блокирования). Рад видеть, что есть и дополнительные преимущества. - person Jon Coombs; 15.03.2014
comment
Вы должны поставить один знак подчеркивания, чтобы указать, что переменная должна рассматриваться как частная. Опять же, это не мешает кому-то получить к нему доступ. - person igon; 30.09.2014
comment
@miya, о да, это так, и он получил это от документация - person Sнаđошƒаӽ; 15.01.2016
comment
Гвидо ответил на этот вопрос. Основная причина, по которой (почти) все обнаруживаемое, заключалась в отладке: когда при отладке вам часто нужно пробивать абстракции - я добавил это как комментарий, потому что уже слишком поздно - слишком много ответов. - person Peter M. - stands for Monica; 01.02.2016
comment
Если следовать критерию предотвращения преднамеренного доступа, большинство языков ООП не поддерживают действительно закрытые члены. Например, в C ++ у вас есть прямой доступ к памяти, а в доверенном коде C # можно использовать частное отражение. - person CodesInChaos; 13.07.2016
comment
Вот почему я никогда не балуюсь классами, интерфейс которых был разработан мной. Каждый, кто может его подклассифицировать, знает, над чем он работает, и, скорее всего, у него будет причина перегрузить определенные вещи, поэтому одного подчеркивания достаточно, чтобы сделать методы и свойства приватными. Я действительно использую dunders при реализации интерфейсов, разработанных другими, чтобы не загромождать api и предотвратить ошибки в случае, если они разделены на подклассы на основе знаний об их ABS. Хорошая причина для использования dunders - это, например, реализация io.BufferedIOBase, где ничего не должно мешать работе буферов. - person Bachsau; 28.11.2018

Пример частной функции

import re
import inspect

class MyClass :

    def __init__(self) :
        pass

    def private_function ( self ) :
        try :
            function_call = inspect.stack()[1][4][0].strip()

            # See if the function_call has "self." in the begining
            matched = re.match( '^self\.', function_call )
            if not matched :
                print 'This is Private Function, Go Away'
                return
        except :
            print 'This is Private Function, Go Away'
            return

        # This is the real Function, only accessible inside class #
        print 'Hey, Welcome in to function'

    def public_function ( self ) :
        # i can call private function from inside the class
        self.private_function()

### End ###
person arun    schedule 30.06.2010
comment
self = MyClass() self.private_function(). : D Конечно, это не работает в классах, но вам просто нужно определить пользовательскую функцию: def foo(self): self.private_function() - person Casey Kuball; 08.05.2012
comment
На всякий случай непонятно: никогда не делайте этого в реальном коде;) - person Sudo Bash; 12.07.2013
comment
Я бы не стал загружать регулярное выражение только для того, чтобы проверить выражение /^.../, сэкономить время и использовать 0 == function_call.index('self.') - person ThorSummoner; 03.07.2014
comment
@ThorSummoner Или просто function_call.startswith('self.'). - person nyuszika7h; 27.08.2014
comment
inspect.stack()[1][4][0].strip() ‹- что это за магические числа 1, 4 и 0? - person akhy; 23.06.2016
comment
self - это всего лишь соглашение. можно использовать другое имя для первого аргумента - person akiva; 18.07.2016
comment
@arun, почему 1 4 0? - person Iulian Onofrei; 21.04.2017
comment
но когда я вызываю obj.public_function () ... он все еще показывает «Это закрытая функция, уходи». не должен ли он показывать «добро пожаловать в работу» - person Jai; 30.05.2017
comment
@SudoBash - идиотский вопрос: почему бы не использовать это в реальном коде? - person Shuklaswag; 07.02.2018
comment
@Shuklaswag Это усложняет работу с вашим кодом, поскольку создает препятствия на пути его отладки. Попытки обойти правила языка с ненужной смекалкой редко заканчиваются хорошо. (Он также не блокирует публичные вызовы функции). - person Will; 22.11.2018
comment
Эту проблему можно довольно легко решить, выполнив self = MyClass(); self.private_function(), и она не работает при вызове с использованием x = self.private_function() внутри метода. - person Will; 22.11.2018
comment
не уверен, что понимаю этот ответ. Он демонстрирует, как иметь действительно частный метод, но не отвечает на вопрос, почему у pyhthon нет действительно частных методов? - person 463035818_is_not_a_number; 22.01.2019

Когда я впервые перешел с Java на Python, я ненавидел это. Это до смерти напугало меня.

Сегодня это может быть единственное, что мне больше всего нравится в Python.

Мне нравится находиться на платформе, где люди доверяют друг другу и не чувствуют, что им нужно строить непроницаемые стены вокруг своего кода. В строго инкапсулированных языках, если в API есть ошибка, и вы выяснили, что идет не так, вы все равно не сможете ее обойти, потому что необходимый метод является частным. В Python позиция такая: «конечно». Если вы думаете, что понимаете ситуацию, возможно, вы даже читали ее, тогда все, что мы можем сказать, - это «удачи!».

Помните, что инкапсуляция даже не слабо связана с «безопасностью» или защитой от детей на лужайке. Это просто еще один шаблон, который следует использовать, чтобы упростить понимание кода.

person Thomas Ahle    schedule 22.12.2009
comment
@CamJackson Javascript - ваш пример ?? Единственный широко используемый язык с наследованием на основе прототипов и язык, который поддерживает функциональное программирование? Я думаю, что JS намного сложнее выучить, чем большинство других языков, поскольку он требует нескольких шагов, ортогональных по сравнению с традиционным ООП. Не то чтобы это мешало идиотам писать JS, они просто этого не знают;) - person K.Steff; 10.04.2012
comment
@Sudar Да, когда мы говорим о культуре принуждения программистов к написанию вещей определенным образом, Java, вероятно, является лучшей «противоположностью» Python в этом отношении. Но Javascript меня раздражает по-другому: P (см. Мой последний комментарий) - person Cam Jackson; 22.06.2012
comment
API-интерфейсы на самом деле являются действительно хорошим примером того, почему инкапсуляция важна и когда предпочтительнее использовать частные методы. Метод, предназначенный как частный, может исчезнуть, изменить подпись или, что хуже всего, изменить поведение - и все это без предупреждения - в любой последующей новой версии. Будет ли ваш умный взрослый член команды действительно помнить, что через год, когда вы обновляете, она получила доступ к предполагаемому частному методу? Будет ли она там больше работать? - person einnocent; 10.01.2014
comment
Я не согласен с этим аргументом. В производственном коде я, скорее всего, никогда не буду использовать API, в котором есть ошибка, которая заставляет меня менять публичные члены, чтобы заставить его работать. API должен работать. Если этого не произойдет, я бы отправил отчет об ошибке или сам сделал такой же API. Мне не нравится эта философия, и я не очень люблю Python, хотя с его синтаксисом интересно писать небольшие скрипты на ... - person Yngve Sneen Lindal; 19.02.2014
comment
Никто не заставляет вас использовать недокументированные API, но если вы этого хотите, кто вам скажет? Модульное тестирование приходит на ум как вариант использования. - person Thomas Ahle; 08.04.2014
comment
В Java есть Method.setAccessible и Field.setAccessible. Также страшно? - person Tony; 24.04.2014
comment
Принуждение в Java и C ++ происходит не потому, что Java не доверяет пользователю, в то время как Python. Это потому, что компилятор и / или виртуальная машина могут делать различные предположения, имея дело с тем, как он ведет свою деятельность, если он знает эту информацию, например, C ++ может пропустить весь уровень косвенного обращения, используя обычные старые вызовы C вместо виртуальных вызовов, и что имеет значение, когда вы работаете с высокопроизводительными или высокоточными материалами. Python по своей природе не может эффективно использовать информацию без ущерба для ее динамизма. Оба языка нацелены на разные вещи, поэтому ни один из них не ошибается. - person Shayne; 04.09.2016
comment
Я противоположен твоему комментарию. Я пришел с Python и начал изучать Java и C ++. Личное - это не недоверие товарищам по команде. Без распространенных ошибок, когда новый разработчик в команде обращается к методу, выходящему за рамки бизнес-логики. то, что должно быть частным и вызываться специально с помощью некоторой логики, теперь стало общедоступным и может вызываться извне. еще страшнее, когда разработчик, совершающий эту ошибку, делает это на общедоступной конечной точке, открывая приложение для sec. уязвимости. Мне нравится питон, но я ненавижу этот его аспект. - person continuousqa; 01.03.2019
comment
Это самое определение. может быть сек. недостаток. разработчики приходят и уходят командами. разработчику может быть поручено добавить общедоступную конечную точку, которая позволяет аффилированным лицам передавать новых регистрантов для создания пользователей. Однако сказал разработчик, перепрофилирует создание учетной записи, сделанное другими разработчиками. Класс создания учетной записи вызывает несколько методов, которые проверяют домены на предмет мошенничества. Но этот новый разработчик напрямую обращается к финальному методу, передавая значение для проверки домена. теперь общедоступная конечная точка обходит проверки на мошенничество. Если бы этот последний метод был частным, ничего бы этого не произошло. это заставит его течь через автобус. логика. - person continuousqa; 01.03.2019
comment
Мы не делаем методы частными и общедоступными в целях безопасности. Мы делаем их, чтобы пользователи не могли нанести серьезный ущерб состоянию и писать программы с использованием изменчивых методов. Открытый метод представляет собой контракт, если я дам вам A, вы получите B. Частные методы не представляют собой контракт. Я могу изменить логику, которая превращает A в B, сколько мне нужно, пока интерфейс взаимодействия по-прежнему выполняет контракт. Если я дам вам доступ к частным методам, вы будете их использовать. Затем, когда я меняю реализацию, ваша программа ломается. Этого не происходит с общедоступными методами, составляющими контракт. - person TheBatman; 23.04.2019
comment
Мне нравится находиться на платформе, где люди доверяют друг другу и не чувствуют, что им нужно строить непроницаемые стены вокруг своего кода. Абсолютная чушь. Отказ от установленных принципов дизайна не заставит ваших коллег полюбить вас, это как раз наоборот. Python во многих отношениях никогда не достигнет структуры и формализма типизированных языков JVM или функционального чутья Haskell. Это хорошо для некоторых вещей, но не нужно красить свинью помадой. - person Abhijit Sarkar; 26.08.2020
comment
@einnocent Меня не убеждает, что приватный метод может измениться в любой момент без уведомления. Фактически то же самое можно применить к Python, docs.python.org/3 /tutorial/classes.html#tut-private, _underscore_method() следует рассматривать как деталь реализации. Таким образом, потребитель класса должен принять во внимание, что он может измениться в любой момент. Если кто-то использует ваши частные методы в своем производственном коде, то это не ваша проблема, если вы измените свои личные данные. - person Qback; 31.08.2020
comment
Самая большая ошибка Java заключалась в том, чтобы не различать общедоступный и опубликованный метод (метод, который должен вызываться извне jar), соединение python в этой ошибке делает все видимым. В любом достаточно большом проекте управление релизами и зависимостями превращается в полный кошмар (добавьте сверху, что некоторые ошибки могут быть обнаружены только во время выполнения, а тикающая бомба обслуживается) - person Alessandro Teruzzi; 18.09.2020

Из http://www.faqs.org/docs/diveintopython/fileinfo_private.html

Строго говоря, частные методы доступны за пределами своего класса, но не так легко доступны. В Python нет ничего по-настоящему частного; внутренне имена частных методов и атрибутов изменяются и извлекаются на лету, чтобы они казались недоступными по заданным им именам. Вы можете получить доступ к методу __parse класса MP3FileInfo по имени _MP3FileInfo__parse. Признайте, что это интересно, а затем пообещайте никогда, никогда не делать этого в реальном коде. Частные методы являются частными по какой-то причине, но, как и многие другие вещи в Python, их конфиденциальность в конечном итоге является вопросом соглашения, а не силы.

person xsl    schedule 16.09.2008
comment
или, как выразился Гвидо ван Россум: мы все взрослые. - person ; 06.10.2008
comment
-1: это просто неправильно. Двойное подчеркивание никогда не предназначено для использования в первую очередь как закрытое. Ответ от Alya ниже показывает истинное намерение синтаксиса искажения имени. Настоящее соглашение - это одно подчеркивание. - person nosklo; 15.10.2009
comment
Попробуйте использовать только одно подчеркивание, и вы увидите результат. @nosklo - person Billal Begueradj; 07.02.2017

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

Если вам действительно нужно что-то частное, вы можете реализовать это в расширении (например, в C для CPython). Однако в большинстве случаев вы просто изучаете питонический образ действий.

person Tony Meyer    schedule 16.09.2008
comment
так есть ли какой-то протокол-оболочка, который я должен использовать для доступа к защищенной переменной? - person intuited; 10.05.2010
comment
Защищенных переменных нет больше, чем частных. Если вы хотите получить доступ к атрибуту, который начинается с подчеркивания, вы можете просто сделать это (но обратите внимание, что автор этого не одобряет). Если вам необходимо получить доступ к атрибуту, который начинается с двойного подчеркивания, вы можете изменить имя самостоятельно, но вы почти наверняка не захотите этого делать. - person Tony Meyer; 13.05.2010

Это не похоже на то, что вы абсолютно не можете обойти конфиденциальность членов на любом языке (арифметика указателей в C ++, отражения в .NET / Java).

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

Изменить: вы не пытаетесь защитить свои вещи с помощью OO-инкапсуляции, не так ли?

person Maximilian    schedule 16.09.2008
comment
Нисколько. Я просто подчеркиваю, что было бы странно давать разработчику простой и, на мой взгляд, волшебный способ доступа к «частным» свойствам. - person willurd; 16.09.2008
comment
Да, я просто попытался проиллюстрировать это. Если вы сделаете его закрытым, вам не следует обращаться к нему напрямую, заставляя компилятор жаловаться. Но действительно очень хочется сделать это, он может. Но да, на Python это проще, чем на большинстве других языков. - person Maximilian; 16.09.2008
comment
В Java вы действительно можете защитить данные с помощью инкапсуляции, но для этого нужно быть умным, запускать ненадежный код в SecurityManager и быть очень осторожным. Даже Oracle иногда ошибается. - person Antimony; 24.04.2013

Важная заметка:

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

Таким образом, __name является частным, а _classname__name - общедоступным.

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

https://docs.python.org/3/tutorial/classes.html#tut-private

Пример

class Cat:
    def __init__(self, name='unnamed'):
        self.name = name
    def __print_my_name(self):
        print(self.name)
        
        
tom = Cat()
tom.__print_my_name() #Error
tom._Cat__print_my_name() #Prints name
person Moradnejad    schedule 24.11.2020
comment
Это не важное обновление, это всегда было правдой. Заменив 3 на 2 в вашей ссылке, docs.python.org/ 2 / tutorial / classes.html # tut-private, показывает почти тот же текст, что и вы ответили. НЕ обновление. - person John; 08.07.2021

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

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

person Nickolay    schedule 16.09.2008

Аналогичное поведение наблюдается, когда имена атрибутов модуля начинаются с одного символа подчеркивания (например, _foo).

Атрибуты модуля, названные как таковые, не будут скопированы в модуль импорта при использовании метода from*, например:

from bar import *

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

person Ross    schedule 17.09.2008

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

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

person ctcherry    schedule 16.09.2008

В Python 3.4 это поведение:

>>> class Foo:
        def __init__(self):
                pass
        def __privateMethod(self):
                return 3
        def invoke(self):
                return self.__privateMethod()


>>> help(Foo)
Help on class Foo in module __main__:

class Foo(builtins.object)
 |  Methods defined here:
 |
 |  __init__(self)
 |
 |  invoke(self)
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)

 >>> f = Foo()
 >>> f.invoke()
 3
 >>> f.__privateMethod()
 Traceback (most recent call last):
   File "<pyshell#47>", line 1, in <module>
     f.__privateMethod()
 AttributeError: 'Foo' object has no attribute '__privateMethod'

https://docs.python.org/3/tutorial/classes.html#tut-private

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

Даже если вопрос старый, я надеюсь, что мой фрагмент может быть полезен.

person Alberto    schedule 24.08.2016

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

obj._MyClass__myPrivateMethod()

Я перешел с C #, и сначала для меня это тоже было странно, но через некоторое время я пришел к мысли, что только то, как разработчики кода Python думают о ООП, отличается.

person Afshin Amiri    schedule 26.04.2018

Почему «частные» методы Python на самом деле не являются частными?

Насколько я понимаю, они не могут быть приватными. Как можно обеспечить конфиденциальность?

Очевидный ответ - «к закрытым членам можно получить доступ только через self», но это не сработает - self не является особенным в Python, это не что иное, как обычно используемое имя для первого параметра функции.

person user200783    schedule 14.01.2019