Родительский класс вызывает закрытый атрибут из дочернего класса - PullRequest
0 голосов
/ 30 июня 2018

В следующем примере с игрушкой последняя строка B (). Show () не вызывает соответствующую версию функции show. Он должен вызывать дочернюю версию, а не родительскую версию. Я думаю, что я должен сделать что-то вроде __class_method (), но не смог найти полный ответ.

Я, конечно, могу перезаписать функцию show в B. Но это, по сути, означает копирование и вставку функции show. Это не элегантно.

## version one ##
class A(object):

    def method(self):
        print("hello")

    def show(self):
        self.method()

class B(A):

    def method(self):
        print("goodbye")


A().show() ## print out hello
B().show() ## print out goodbye

## version two ##    
class A(object):

    def __method(self):
        print("hello")

    def show(self):
        self.__method()

class B(A):

    def __method(self):
        print("goodbye")


A().show() ## print out hello
B().show() ## print out hello

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Чтобы сохранить приватные методы каждого класса и иметь доступ к ним, вы можете сделать что-то вроде этого:

class A(object):

    def __method(self):
        print("hello")
    method = __method

    def show(self):
        self.method()


class B(A):

    def __method(self):
        print("goodbye")
    method = __method

выход:

hello
goodbye
0 голосов
/ 30 июня 2018

Если вы начнете имя метода с двух подчеркиваний, оно станет доступным только из этого класса. Рассмотрим следующий пример:

class A():
    def __m(self):
        pass
    def m(self):
        print(self.__m)

A().m()  # <bound method A.__m of <__main__.A object at 0x10e0c1898>>
A().__m()  # AttributeError: 'A' object has no attribute '__m'

Так что же случилось с A().__m? Проверьте A.__dict__, где атрибуты ищутся:

>>> A.__dict__
mappingproxy({'__module__': '__main__', '_A__m': <function A.__m at 0x10e0ab730>, 'm': <function A.m at 0x10e0ab7b8>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})

Самое главное:

'_A__m': <function A.__m at 0x10e0ab730>

Итак, функция, которую вы написали, __m, переименована в _A__m. Вы не предназначены для доступа к этим методам из-за пределов класса.

Если в вашем классе есть метод show, который вызывает метод __method (который начинается с __), он будет вызывать только этот метод этого класса, потому что он никогда не узнает о _B__method , только около _A__method.

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

Если вам действительно нужно, чтобы __method метод B был приватным, тогда да, B также должен переопределить show:

class A(object):
    def __method(self):
        print("hello")
    def show(self):
        self.__method()

class B(A):
    def __method(self):
        print("goodbye")
    def show(self):
        self.__method()

A().show() ## print out hello
B().show() ## print out goodbye
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...