Подтвердить что ты не робот

Python "защищенные" атрибуты

Как мне получить доступ к приватному атрибуту родительского класса из подкласса (не делая его общедоступным)?

4b9b3361

Ответ 1

Мое понимание соглашения Python

  • _member защищен
  • __ член закрыт.

Параметры, если вы управляете родительским классом

  • Сделать это защищенным, а не частным так как это похоже на то, что вы действительно хотите
  • Используйте getter (@property def _protected_access_to_member...) для ограничения защищенного доступа

Если вы не контролируете его

  • Отменить изменение имени. если ты dir (объект) вы увидите имена что-то вроде _Class__member, которое что делает Python для ведения __ "сделай это частным". Нет действительно закрытый в python. Это, вероятно, считается злом.

Ответ 2

Две философии защиты

Некоторые разработчики языка подписываются на следующее предположение:

"Многие программисты безответственны, туманны или оба."

Эти разработчики языка будут испытывать соблазн защитить программистов друг от друга, введя спецификатор private на свой язык. Вскоре они признают, что это часто слишком негибкие и вводят protected.

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

Следовательно, _myfield в Python означает что-то вроде "Дизайнер этого модуля делает некоторые неочевидные вещи с этим атрибутом, поэтому, пожалуйста, не изменяйте его и избегайте даже чтения, если сможете - подходящие способы для доступа к соответствующей информации."

Если вы не можете оставаться в стороне от доступа к _myfield (например, в особых случаях в подклассе), вы просто получаете к нему доступ.

Ответ 3

Используя @property и @name.setter, чтобы сделать то, что вы хотите

например

class Stock(object):

    def __init__(self, stockName):

        # '_' is just a convention and does nothing
        self.__stockName  = stockName   # private now


    @property # when you do Stock.name, it will call this function
    def name(self):
        return self.__stockName

    @name.setter # when you do Stock.name = x, it will call this function
    def name(self, name):
        self.__stockName = name

if __name__ == "__main__":
      myStock = Stock("stock111")

      myStock.__stockName  # It is private. You can't access it.

      #Now you can myStock.name
      N = float(raw_input("input to your stock: " + str(myStock.name)+" ? "))

Ответ 4

если имя переменной - "__secret", а имя класса - "MyClass", вы можете получить доступ к нему, как это, в экземпляре с именем "var"

var._MyClass__secret

Соглашение о том, чтобы предлагать/эмулировать защиту, это назвать его с помощью верхнего подчеркивания: self._protected_variable = 10

Конечно, любой может изменить его, если он действительно хочет.

Ответ 5

Создайте метод доступа, если я не пропущу что-то:

def get_private_attrib(self):
  return self.__privateWhatever

Ответ 6

Никто не отвечает на исходный вопрос

как получить доступ к частному атрибуту родительского класса из подкласса

Итак, вот простой пример использования, демонстрирующий два варианта: доступ к родительскому классу __ private variables и использование @декоратор свойств:

class Family:

    def __init__(self, name):
        self.__family_name = name

    @property
    def name(self):
        return self.__family_name


class Child(Family):

    def __init__(self, first_name, last_name):
        super(Child, self).__init__(last_name)
        self.__child_name = first_name


    @property
    def name(self):
        return (self.__child_name, super(Child, self).name)


if __name__ == '__main__':
    my_child = Child("Albert", "Einstein")

    # print (my_child.__child_name)         # AttributeError - trying to access private attribute '__child_name'
    # print (my_child.__family_name)        # AttributeError - trying to access private attribute '__family_name'
    print (my_child._Child__child_name)     # Prints "Albert" - By accessing __child_name of Child sub-class
    print (my_child._Family__family_name)   # Prints "Einstein" - By accessing __family_name in Family super-class
    print (" ".join(my_child.name))         # Prints "Albert Einstein" - By using @property decorators in Child and Family 

Ответ 7

Я думаю, что этот код немного яснее, чем Стив. Стив ответ был самым полезным для того, что я пытаюсь сделать, так что спасибо! Я тестировал это с помощью python 2.7 и python 3.6.

#! /usr/bin/python
#
# From https://stackoverflow.com/info/797771/python-protected-attributes
from __future__ import print_function
import sys

class Stock(object):

    def __init__(self, stockName):

        # '_' is just a convention and does nothing
        self.__stockName  = stockName   # private now


    @property # when you do Stock.name, it will call this function
    def name(self):
        print("In the getter, __stockName is %s" % self.__stockName, file=sys.stderr)
        return self.__stockName

    @name.setter # when you do Stock.name = x, it will call this function
    def name(self, name):
        print("In the setter, name is %s will become %s" % ( self.__stockName, name), file=sys.stderr)
        self.__stockName = name

if __name__ == "__main__":
    myStock = Stock("stock111")

    try:
        myStock.__stockName  # It is private. You can't access it.
    except AttributeError as a:
        print("As expect, raised AttributeError", str(a), file=sys.stderr )
    else:
        print("myStock.__stockName did did *not* raise an AttributeError exception")


    #Now you can myStock.name
    myStock.name = "Murphy"
    N = float(input("input to your stock: " + str(myStock.name)+" ? "))
    print("The value of %s is %s" % (myStock.name, N) )