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 Outer
método de la Inner
clase desde la clase?
python
scope
nested
inner-classes
T. Stone
fuente
fuente
self.<original_parent_name>
y obtener la clase original, no la nueva clase de la que son una subclase . Espero que las personas que lean esto puedan visualizar este escenario difícil y ver el sentido de preguntas como esta.Respuestas:
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 de 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 usar clases anidadas, ya que el anidamiento no implica ninguna relación particular entre las clases internas y externas.
fuente
Estás intentando acceder a la instancia de clase de Outer, desde la instancia de clase interna. Así que solo use el método de fábrica para construir una instancia interna y pasarle una instancia externa.
fuente
tal vez estoy enojado, pero esto parece muy fácil de hecho: la cuestión es hacer que su clase interna dentro de un método de la clase externa ...
Además ... "self" solo se usa por convención, por lo que puede hacer esto:
Se podría objetar que luego no puede crear esta clase interna desde fuera de la clase externa ... pero esto no es cierto:
luego, en algún lugar a millas de distancia:
incluso empuje un poco el bote y extienda esta clase interna (NB para que super () funcione, debe cambiar la firma de clase de mooble a "class mooble (objeto)"
luego
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:
fuente
¿Quiere usar la herencia en lugar de anidar clases como esta? Lo que estás haciendo no tiene mucho sentido en Python.
Puede acceder a
Outer
some_method simplemente haciendo referenciaOuter.some_method
dentro de los métodos de la clase interna, pero no va a funcionar como espera. Por ejemplo, si prueba esto:... obtendrá un TypeError al inicializar un
Inner
objeto, porqueOuter.some_method
espera recibir unaOuter
instancia como primer argumento. (En el ejemplo anterior, básicamente está intentando llamarsome_method
como un método de clase deOuter
).fuente
Puede acceder fácilmente a la clase externa usando metaclase: después de la creación de la clase externa, verifique su atributo dict para cualquier clase (o aplique cualquier lógica que necesite, el mío es solo un ejemplo trivial) y establezca los valores correspondientes:
Con este enfoque, puede vincular y referir fácilmente dos clases entre sí.
fuente
He creado un código Python para usar una clase externa de su clase interna , basado en una buena idea de otra respuesta para esta pregunta. Creo que es breve, simple y fácil de entender.
El código principal, "listo para producción" (sin comentarios, etc.). Recuerde reemplazar todos los valores entre corchetes angulares (por ejemplo
<x>
) con el valor deseado.Explicación de cómo funciona este método (los pasos básicos):
Cree una función nombrada
_subclass_container
para actuar como un contenedor para acceder a la variableself
, una referencia a la clase de nivel superior (del código que se ejecuta dentro de la función).Cree una variable nombrada
_parent_class
que sea una referencia a la variableself
de esta función, a la que_subclass_container
puedan acceder lasself
subclases de (evita conflictos de nombre con otras variables en subclases).Devuelve la subclase / subclases como un diccionario / lista para que el código que llame a la
_subclass_container
función pueda acceder a las subclases internas.En la
__init__
función dentro de la clase de nivel superior (o donde sea necesario), reciba las subclases devueltas de la función_subclass_container
en la variablesubclasses
.Asignar subclases almacenadas en la
subclasses
variable a atributos de la clase de nivel superior.Algunos consejos para facilitar los escenarios:
Haciendo que el código para asignar las subclases a la clase de nivel superior sea más fácil de copiar y usar en clases derivadas de la clase de nivel superior que tienen su
__init__
función cambiada:Inserte antes de la línea 12 en el código principal:
Luego inserte en esta función las líneas 5-6 (del código principal) y reemplace las líneas 4-7 con el siguiente código:
Hacer posible la asignación de subclases a la clase de nivel superior cuando hay muchas / desconocidas cantidades de subclases.
Reemplace la línea 6 con el siguiente código:
Escenario de ejemplo en el que esta solución sería útil y donde el nombre de clase de nivel superior debería ser imposible de obtener:
Se
class a:
crea una clase, denominada "a" ( ). Tiene subclases que necesitan acceder a él (el padre). Una subclase se llama "x1". En esta subclase,a.run_func()
se ejecuta el código .Luego se crea otra clase, llamada "b", derivada de la clase "a" (
class b(a):
). Después de eso, se ejecuta algún códigob.x1()
(llamando a la subfunción "x1" de b, una subclase derivada). Esta función se ejecutaa.run_func()
, llamando a la función "run_func" de la clase "a", no a la función "run_func" de su padre, "b" (como debería), porque la función que se definió en la clase "a" está configurada para referirse a la función de la clase "a", ya que era su padre.Esto causaría problemas (por ejemplo, si
a.run_func
se ha eliminado la función) y la única solución sin reescribir el código en la clasea.x1
sería redefinir la subclasex1
con código actualizado para todas las clases derivadas de la clase "a", lo que obviamente sería difícil y no valdría la pena. eso.fuente
Encontré esto .
Modificado para adaptarse a su pregunta:
Estoy seguro de que de alguna manera puedes escribir un decorador para esto o algo.
relacionado: ¿Cuál es el propósito de las clases internas de Python?
fuente
Otra posibilidad:
fuente
Ampliando el pensamiento convincente de @ tsnorri, que el método externo puede ser un método estático :
Ahora la línea en cuestión debería funcionar en el momento en que realmente se llame.
La última línea del código anterior le da a la clase Inner un método estático que es un clon del método estático Outer.
Esto aprovecha dos características de Python, que las funciones son objetos y el alcance es textual .
... o clase actual en nuestro caso. Así que los objetos "locales" a la definición de la clase Outer (
Inner
ysome_static_method
) pueden ser referidos directamente dentro de esa definición.fuente
Unos años tarde para la fiesta ... pero para ampliar
@mike rodent
la maravillosa respuesta, he proporcionado mi propio ejemplo a continuación que muestra cuán flexible es su solución y por qué debería ser (o debería haber sido) la aceptada. responder.Python 3.7
Salida:
Una vez más, una maravillosa respuesta, ¡apoyos para ti, Mike!
fuente
Es demasiado simple:
Entrada:
Salida
clase A func1
clase B func1
fuente
func1
. Y, igualmente divertido, creas unA
dentro del constructor deB
, que NO es en absoluto elA
objeto de clase exterior de ese particularB
.