¿Cómo acceder a la clase externa desde una clase interna?

Resuelto T. Stone asked hace 14 años • 16 respuestas

Tengo una situación así...

class Outer(object):

    def some_method(self):
        # do something

    class Inner(object):
        def __init__(self):
            self.Outer.some_method()    # <-- this is the line in question

¿ Cómo puedo acceder al Outermétodo de la clase desde la Innerclase?

T. Stone avatar Jan 08 '10 06:01 T. Stone
Aceptado

Estás intentando acceder a la instancia de clase externa, desde la instancia de clase interna. Así que simplemente use el método de fábrica para construir una instancia interna y pasarle una instancia externa.

class Outer(object):

    def createInner(self):
        return Outer.Inner(self)

    class Inner(object):
        def __init__(self, outer_instance):
            self.outer_instance = outer_instance
            self.outer_instance.somemethod()

        def inner_method(self):
            self.outer_instance.anothermethod()
Kitlbast avatar Aug 11 '2011 23:08 Kitlbast

Los métodos de una clase anidada no pueden acceder directamente a los atributos de instancia de la clase externa.

Tenga en cuenta que no es necesariamente el caso que exista una instancia de la clase externa incluso cuando haya creado una instancia de la clase interna.

De hecho, a menudo se recomienda no utilizar clases anidadas, ya que el anidamiento no implica ninguna relación particular entre las clases internas y externas.

Daniel Vassallo avatar Jan 07 '2010 23:01 Daniel Vassallo

tal vez estoy enojado, pero esto parece muy fácil: la cuestión es hacer que tu clase interna sea un método de la clase externa...

def do_sthg(self):
    ...

def mess_around(self):

    outer_class_self = self

    class Mooble():
        def do_sthg_different(self):
            ...
            outer_class_self.do_sthg()

Además... "self" sólo se usa por convención, por lo que puedes hacer esto:

def do_sthg(self):
    ...

def mess_around(outer_class_self):

    class Mooble():
        def do_sthg_different(self):
            ...
            outer_class_self.do_sthg()

Se podría objetar que no se puede crear esta clase interna desde fuera de la clase externa... pero esto no es cierto:

class Bumblebee():

    def do_sthg(self):
        print "sthg"
    
    def give_me_an_inner_class(outer_class_self):

        class Mooble():
            def do_sthg_different(self):
                print "something diff\n"
                outer_class_self.do_sthg()
        return Mooble
    

luego, en algún lugar a kilómetros de distancia:

blob = Bumblebee().give_me_an_inner_class()()
blob.do_sthg_different()    

incluso empuje un poco el barco y extienda esta clase interna (NB, para comenzar super()a trabajar, debe cambiar la firma de clase de Mooblea class Mooble(object)).

class InnerBumblebeeWithAddedBounce(Bumblebee().give_me_an_inner_class()):
    def bounce(self):
        print "bounce"
    
    def do_sthg_different(self):
        super(InnerBumblebeeWithAddedBounce, self).do_sthg_different()
        print "and more different"
    

ibwab = InnerBumblebeeWithAddedBounce()    
ibwab.bounce()
ibwab.do_sthg_different()

más tarde

mrh1997 planteó un punto interesante sobre la herencia no común de clases internas entregadas mediante esta técnica. Pero parece que la solución es bastante sencilla:

class Fatty():
    def do_sthg(self):
        pass
    
    class InnerFatty(object):
        pass
            
    def give_me_an_inner_fatty_class(self):
        class ExtendedInnerFatty(Fatty.InnerFatty):
            pass
        return ExtendedInnerFatty
                
fatty1 = Fatty()
fatty2 = Fatty()

innerFattyClass1 = fatty1.give_me_an_inner_fatty_class()
innerFattyClass2 = fatty2.give_me_an_inner_fatty_class()

print (issubclass(innerFattyClass1, Fatty.InnerFatty))
print (issubclass(innerFattyClass2, Fatty.InnerFatty))
mike rodent avatar Aug 22 '2011 19:08 mike rodent