Запустите __init__ только в базовом классе - PullRequest
0 голосов
/ 30 ноября 2018

Я хотел бы иметь метод __init__(), который запускается только в базовом классе, но не запускается в дочерних классах.

Учитывая код здесь:

class base:

    def __init__(self):
        print('Only print this if I am base')

class ext(base):
    ...

foo = ext()

Я получаю следующий результат:

Only print this if I am base

Чем я не являюсь, так что это не то, что я хочу.

Решением может быть просто лучшая архитектура.Очевидно, что ext не является на самом деле расширением base, поскольку base делает то, что ext не делает.

Возможно, двойное наследование является решением проблемы.Имейте базовое наследование от i_print_an_init_message класса и поместите туда __init__().Хотя это кажется излишним.

Также проверка имени класса, чтобы увидеть, выглядит ли имя base неуместным.

Или, может быть, у меня просто есть аргумент в init, который по умолчанию равенFalse.

Есть ли какой-нибудь особенно питонский способ сделать это?

(Пожалуйста, предположите, что я ответил на все комментарии «Почему вы это делаете?». Спасибо!)

Ответы [ 4 ]

0 голосов
/ 30 ноября 2018

Вероятно, должен существовать третий класс, который выступает в роли родителя для base и ext.

class RealBase:
    def __init__(self):
        ...


class Base(RealBase):
    def __init__(self):
        print('Only print this if I am base')


class Ext(RealBase):
    def __init__(self):
        ...    

Ext не должен расширяться Base, если его экземпляры на самом деле не являютсяэкземпляры Base.Вы должны иметь возможность использовать экземпляр дочернего класса везде, где вы можете использовать экземпляр его родителя.

0 голосов
/ 30 ноября 2018

вы можете либо переопределить __init__, либо взломать его с помощью чего-то вроде

class base:
    def __init__(self):
        if self.__class__ == base:
            print('Only print this if I am base')

, если вы хотите, чтобы base.__init__ делал то, что ext.__init__ не должно делать.но это может быть признаком того, что вы должны изменить свой дизайн ... (например, что-то вроде того, что предлагает chepner ).

0 голосов
/ 30 ноября 2018

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

class base:
    def __init__(self):
        print ('base')


class ext(base):
    def __init__(self):
        print('ext')


foo = ext()

, который производит вывод:

ext

, в отличие от конструктора, который:

class base:
    def __init__(self):
        print ('base')


class ext(base):
    def __init__(self):
        super().__init__()
        print('ext')


foo = ext()

производит результат:

base
ext
0 голосов
/ 30 ноября 2018

Я думаю, что решение аргумента - лучшее.Только человек, использующий базу, мог бы передать аргумент top, иначе мы получим требуемое поведение.

class base:

    def __init__(self, top=False):
        if top:
            print('Only print this if I am base')

class ext(base):
...

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