2012-08-17 14 views
9

Estoy aprendiendo Python a través de libros e Internet y estoy atrapado en un problema de clase.python: crear instancia de clase en otra clase (con un ejemplo genérico)

2 preguntas:

  1. ¿Cómo se crea una instancia de una clase en otra clase (separado)?
  2. ¿Cómo paso variables entre la clase y la clase anidada (?)?

Cuando intento crear una instancia de una clase dentro de otra clase (separada), puedo hacerlo dentro de un método. Aquí está el código:

import os 

class FOO(): 
def __init__(self): 
    self.values = [2, 4, 6, 8] 

def do_something(self, x, y): 
    os.system("clear") 
    z = self.values[x] * self.values[y] 
    print "%r * %r = %r" % (self.values[x], self.values[y], z) 


class BAR(): 
def __init__(self): 
    pass 

def something_else(self, a, b): 
    foo1 = FOO() 
    foo1.do_something(a, b) 

bar = BAR() 
bar.something_else(1, 2) 

¿Esta, sin embargo, me permite acceder a la clase FOO y es información en otros métodos de barras? ¿Si es así, cómo?

He intentado lo siguiente y tiene un error:

import os 

class FOO(): 
def __init__(self): 
    self.values = [2, 4, 6, 8] 

def do_something(self, x, y): 
    os.system("clear") 
    z = self.values[x] * self.values[y] 
    print "%r * %r = %r" % (self.values[x], self.values[y], z) 


class BAR(): 
def __init__(self): 
    foo1 = FOO() 

def something_else(self, a, b): 
    foo1.do_something(a, b) 

bar = BAR() 
bar.something_else(1, 2) 

Aquí está el error:

Traceback (most recent call last): 
File "cwic.py", line 22, in <module> 
bar.something_else(1, 2) 
File "cwic.py", line 19, in something_else 
foo1.do_something(a, b) 
NameError: global name 'foo1' is not defined 

me sale el mismo error cuando utilicé:

def __init__(self): 
    self.foo1 = FOO() 

Además, ¿Cómo debería pasar los 'valores' de una clase a la otra?

Háganme saber si mi enfoque general y/o sintaxis son incorrectos. Todas y cada una de las sugerencias son bienvenidas (incluyendo buenas lecturas) ya que estoy recién aprendiendo. Gracias.

Respuesta

4

Todos los atributos de una instancia o de clase a través de self que se pasa como primer argumento a todos los métodos. Es por eso que ha obtenido correctamente la firma del método something_else(self, a, b) en comparación con solo something_else(a, b) como podría hacerlo con otros idiomas. Por lo que está buscando:

class BAR(): 
     def __init__(self): 
      self.foo1 = FOO() 

    def something_else(self, a, b): 
     self.foo1.do_something(a, b) 

Tenga en cuenta que yo no es una palabra clave, es sólo un nombre de parámetro de como a y b, por lo que podría, por ejemplo, tener la tentación de utilizar this lugar si eres de una Fondo de Java ... ¡No lo hagas! hay una convención muy fuerte para usar self para este propósito y harás que mucha gente (incluyéndote a ti mismo eventualmente) se enoje mucho si usas cualquier otra cosa.

Con respecto a la aprobación de valores no estoy seguro de lo que quiere decir, puede acceder a ellos a través de instancias como foo1.an_attribute o pasarlos como argumentos a funciones como function(arg) pero parece que utilizó ambas técnicas en su ejemplo, así que No estoy seguro de qué más estás buscando ...

Editar

En respuesta al comentario de @ dwstein, no estoy seguro de cómo se hace en VB, pero aquí es una forma de pasar argumentos al crear una instancia de una clase.

Si nos fijamos en su clase:

class BAR(): 
    def __init__(self): 
     self.foo1 = FOO() 

podemos cambiar eso para aceptar una Baz argumento cambiando segunda línea de def __init__(self, baz): y luego, si queremos podemos hacer baz un atributo de nuestra nueva instancia de BAR estableciendo self.baz = baz. Espero que ayude.

+0

Gracias por su minuciosa respuesta! Muy útil. Estoy tratando de entender cómo pasé la información de una clase a otra. Supongo que he visto argumentos como parte de las definiciones de clase y me pregunto si esa es la manera correcta. Pero, no sé cómo usar esa funcionalidad. por cierto, tengo un fondo de VBA. – dwstein

2

En python siempre tiene que usar el prefijo "self" al acceder a los miembros de su instancia de clase. Trate

class BAR(): 
    def __init__(self): 
     self.foo1 = FOO() 

    def something_else(self, a, b): 
     self.foo1.do_something(a, b) 
1

Usted está en el camino correcto, vuelva a: Se accede a

class BAR(): 
    def __init__(self): 
     self.foo1 = FOO() 

    def something_else(self, a, b): 
     self.foo1.do_something(a, b) 
0

No estoy seguro de entender su pregunta, que es más un reflejo de mí que de usted. Si entiendo lo que estás buscando, quieres crear una instancia de una clase dentro de un método de clase. Ahora, podría estar fuera de la base aquí, así que si esto es confuso, es posible que esté respondiendo una pregunta diferente a la de su pregunta.

#! /usr/bin/env python3 

class MyClass (object): 

    instance_list = [] 

    def __init__ (self, arg1, arg2): 
    self.arg1 = arg1 
    self.arg2 = arg2 

    @classmethod 
    def make_instances(cls): 
    for a1 in range(1,4): 
     for a2 in range(1,3): 
     cls.instance_list.append(MyClass(a1, a2)) 

    @classmethod 
    def dump_instance_list (cls): 
    for instance in cls.instance_list: 
     print("arg1= %d\targ2= %d" % (instance.arg1, instance.arg2)) 

if __name__ == "__main__" : 
    MyClass.make_instances() 
    MyClass.dump_instance_list() 
    an_instance = MyClass(14, 22) 
    print("An instance: %d, %d" % (an_instance.arg1, an_instance.arg2)) 

Lo que hace este programa es crear una clase, MyClass, que tiene un objeto de clase, instance_list. instance_list va a ser una lista de instancias. el método de clase make_instances hace justamente eso: crea instancias y rellena instance_list. Al final del programa, creo an_instance de la misma forma en que uno "normalmente" crearía una instancia. Entonces an_instance es un objeto de la clase MyClass.

Espero que esto sea útil

Cuestiones relacionadas