Создание метода private в подклассе python - PullRequest
25 голосов
/ 16 января 2009

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

class A:
    def __init__(self):
        #do something here

    def method(self):
        #some code here

class B(A):
    def __init__(self):
        A.__init__(self)
        #additional initialization goes here

    def method(self):
        #this overrides the method ( and possibly make it private here )

с этого момента, я не хочу, чтобы какой-либо класс, выходящий из B, мог вызывать method. Возможно ли это?

РЕДАКТИРОВАТЬ: «логическая» причина этого в том, что я не хочу, чтобы пользователи вызывали методы в неправильном порядке.

Ответы [ 13 ]

1 голос
/ 08 февраля 2012

Даже среди соглашающихся взрослых есть причины, по которым вы не хотите показывать методы производному классу. Вопрос в том, могу ли я иметь иерархию, подобную Parent> Child, где пользователь может наследовать от Parent или Child, но не подвергаться никаким закрытым или защищенным методам. В следующем примере Child явно перегружает Parent .__ private, не раскрывая его.

class Parent(object):
    def __private(self):
        print 'Parent'

    def go(self):
        self.__private()

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
        self._Parent__private = self.__private

    def __private(self):
        print 'Child'
0 голосов
/ 12 января 2019

В этой теме есть много хороших ответов, но вот несколько практичный ответ с практической точки зрения:

Вам нужно необходимо избегать большого количества частных членов из открытых API, intellisense, документов, import * и т. Д. Поэтому всегда присоединяйте _ или __ к этим членам.

Большой вопрос: должно ли это быть _ или __? Цель ООП purist - всегда присоединять __ к закрытым членам и _ для защищенных методов. __ делает имя искажения и затрудняет использование таких вещей, как setattrib, тестовые среды и снижает удобочитаемость. Поэтому я лично стараюсь избегать __ как можно больше и использовать _ для частных пользователей.

Но как насчет защищенных членов, которые мы хотим, чтобы производный класс использовал, но не как публичный API. Я предпочитаю не использовать подчеркивание вообще. Это позволяет этим членам получать публичные документы. Затем мы полагаемся на docstring, чтобы сообщить пользователю, что это защищенные члены, например:

class Class1:
  def _private1():
    pass

  def protected1():
    """(for derived classes) Does XYZ."""
    pass

  def public1()
    pass
0 голосов
/ 12 января 2019

В этой теме есть много хороших ответов, но вот несколько практичный ответ с практической точки зрения:

Вам необходимо скрыть (или документ) переменные и методы низкого уровня от общедоступных API. Поэтому всегда присоединяйте _ или __ к этим членам. Большой вопрос: должно ли это быть _ или __? Перспектива пуристического ООП состоит в том, чтобы всегда присоединять __ к закрытым членам и _ к «защищенным» методам (то есть доступным, переопределяемым из производного класса). __ гарантирует, что производный класс не может переопределить его. С другой стороны, это также затрудняет использование таких вещей, как setattr, тестируемость и читаемость.

Мое личное мнение (а также руководство по стилю Google ) состоит в том, чтобы максимально избегать ___ и использовать _ для частных пользователей.

А как насчет защищенных членов? Как мы говорим пользователям нашей библиотеки, что они должны / должны переопределить? Здесь я предпочитаю не использовать подчеркивание для защищенных членов и вместо этого полагаться на комментарии строки документации и, необязательно, @abstractmethod в базовом классе. Одним из преимуществ здесь является то, что защищенные члены не будут исключены из различных генераторов документации.

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