Jak provádět běžné post-inicializace úkoly v zděděných tříd Python?

hlasů
5

Inicializace Proces skupiny tříd, které sdílejí společnou rodiče může být rozdělena na tři části: společná část 1, třída specifická část, společná část 2. V současné době jsou první dvě části jsou volány z funkce __init__ každé třídy dítěte, ale druhá společná část musí být volána odděleně Například:

class BaseClass:
    def __init__(self):
    print 'base __init__'
    self.common1()

    def common1(self):
    print 'common 1'

    def finalizeInitialization(self):
    print 'finalizeInitialization [common2]'


class Subclass1(BaseClass):
    def __init__(self):
    BaseClass.__init__(self)
        self.specific()

    def specific(self):
    print 'specific'


if __name__ == '__main__':
    s = Subclass1() #Don't forget to finalize the initialization
    s.finalizeInitialization()  # now the object is fully initialized

Existuje způsob, jak nemít volat finalizeInitialization ()?

EDIT lze přepojit k finalizeInitialization () do Subclass1 je __init__ (jako v S.Lott odpověď ). To dělá život jednodušší, ale stále je třeba pamatovat na dokončení inicializace, tentokrát uvnitř „konstruktor“. Ať tak či onak neexistuje žádný způsob, jak prosadit plnou inicializaci, což je to, co jsem hledal.

Položena 27/04/2009 v 21:38
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
11

Template Method návrhový vzor na záchranu:

class BaseClass:
    def __init__(self, specifics=None):
        print 'base __init__'
        self.common1()
        if specifics is not None:
            specifics()
        self.finalizeInitialization()

    def common1(self):
        print 'common 1'

    def finalizeInitialization(self):
        print 'finalizeInitialization [common2]'


class Subclass1(BaseClass):
    def __init__(self):
        BaseClass.__init__(self, self.specific)

    def specific(self):
        print 'specific'
Odpovězeno 28/04/2009 v 02:17
zdroj uživatelem

hlasů
6

Verze 1 - přenést všechno.

class Subclass1(BaseClass):
    def __init__(self):
        super( Subclass1, self ).__init__()
        self.specific()
        super( Subclass1, self ).finalizeInitialization()

Verze 2 - delegát jen jeden krok

class BaseClass:
    def __init__(self):
        print 'base __init__'
        self.common1()
        self.specific()
        self.finalizeInitialization()

    def common1(self):
        print 'common 1'

    def finalizeInitialization(self):
        print 'finalizeInitialization [common2]'

    def specific( self ):
        # two choices:
        # if this is "abstract": raise an exception
        # if this is "concrete": pass
Odpovězeno 27/04/2009 v 21:43
zdroj uživatelem

hlasů
1

Podobně jako u přístupu S. Lott, s výjimkou neexistuje žádný způsob (short převažujícího __init__) pro odvozené třídy přepsat (nebo dokonce volat) společné metody:

class BaseClass:
    def __init__(self):
        def common():
            print "common initialization..."

        def final():
            print "common finalization..."

        common()
        self.specific()
        final()

    def final_init(self):
        print "BaseClass.final_init"


class Subclass1(BaseClass):

    def specific(self):
        print "Subclass1.specific"

Možná budete chtít, aby výchozí implementace specificv BaseClasspřípadě, že to není v pořádku vznést AttributeErrorpři vytvoření instance libovolného podtřídy, která neposkytuje vlastní implementaci.

Odpovězeno 28/04/2009 v 03:10
zdroj uživatelem

hlasů
0

Máte-li volat více metod v určitém pořadí to obvykle znamená, že konstrukce má problémy se začínají (to prosakuje detailů implementace). Takže se budu snažit pracovat z tohoto konce.

Na druhou stranu, pokud lidé jsou odvozeny od třídy a mají upravit inicializaci by měli vzít v úvahu důsledky - to není něco, co byste chtěli mít ve svém normálním API. Jinak byste mohli být defenzivní o závěrečné inicializace a zkontrolujte, zda byl nazýván v metodách, které jsou na ní závislé (to nazvat nebo vyvolat výjimku, pokud ne).

Odpovězeno 27/04/2009 v 22:43
zdroj uživatelem

hlasů
0

Co je s voláním finalInitilazation Z podtřídy je init špatně?

   class BaseClass:
        def __init__(self):
            print 'base __init__'
            self.common1()

        def common1(self):
            print 'common 1'

        def finalizeInitialization(self):
            print 'finalizeInitialization [common2]'


    class Subclass1(BaseClass):
        def __init__(self):
            BaseClass.__init__(self)
            self.specific()
            BaseClass.finalizeInitialization(self)

        def specific(self):
            print 'specific'


    if __name__ == '__main__':
        s = Subclass1() #Don't forget to finalize the initialization
        s.finalizeInitialization()  # now the object is fully initialized
Odpovězeno 27/04/2009 v 21:47
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more