2

Ando creando una app y como quiero usar POO todo lo que pueda me asalta la siguiente duda.

class AAA:
    def aaa1():
    def aaa2():

class BBB:
    def bbb1():
    def bbb2():

¿Cómo puedo llamar desde la class AAA al método bb2 de class BBB?, lo que es lo mismo, ¿Cómo puedo hacer lo siguiente?

class AAA:
    def AAA1():
    def AAA2():
        def bbb2() 

Muchisimas gracias.

Eduardo Munizaga
  • 2,694
  • 1
  • 13
  • 34
Eva Rentero
  • 57
  • 1
  • 1
  • 7
  • 3
    No se si tengo clara la duda, en el ejemplo de lo que deseas tienes `def bbb2()` y eso no es llamar, es definir el método. Si es llamar ¿se trataría de un método de instancia, de clase o estático? – FJSevilla Apr 26 '19 at 12:55
  • 3
    Tal como lo tienes, (aparte de que te sobraría el `def` delante de la "llamada" que intentas hacer), `bbb2()` es un método de la clase `BBB`, pero no es un `@staticmethod`, por lo que no puedes llamarlo sin antes haber instanciado la clase. Es decir, tendrías que crear un objeto de tipo `BBB`, haciendo algo como: `b = BBB()` y entonces ya podrías invocar su método: `b.bbb2()`, no importa desde donde, tanto desde `AAA2()` como desde cualquier otro sitio – abulafia Apr 26 '19 at 12:59
  • Hola @abufalia exactamente como indicais falta todo eso, pero mi código es muy extenso y he querido ponerlo en forma de esquema para ser mas sencilla. Ya lo tengo solucionado, me estaba ahogando en un charco, imagino que poco a poco lo pillare mejor. Mil gracias :) – Eva Rentero Apr 26 '19 at 13:23
  • @albufalia lo tuyo tiene todo el sentido y mas pero, en el codigo llamo al método bb2 de la clase BBB desde un bucle IF y al hacerlo como me indicas, b = BBB() y b.bbb2() antes de llegar al método bbb2 me ejecuta la clase BBB, que es lo que no quiero, solo necesito bbb2(). – Eva Rentero Apr 26 '19 at 13:29

3 Answers3

7

El concepto "método de una clase" puede ser poco preciso. Tu ejemplo en realidad muestra algo que yo tiendo a no considerar como "método" propiamente dicho, es simplemente una función definida dentro de una clase, sin más relación con la misma que estar dentro de dicho espacio de nombres. En este caso la única forma de llamarlo desde fuera de la clase (lo que incluye llamarlo desde otra clase) es AAA.aaa2() (ver al final de la respuesta).

En general, nos podemos encontrar con cuatro posibilidades al definir una función/método dentro de una clase en Python:

Método de instancia

Son métodos vinculados a una instancia de la clase, que pueden acceder al estado de la instancia y modificarlo (leer y modificar atributos de instancia). Reciben como primer parámetro la instancia propiamente dicha (por convención se denota con self). Por poder pueden incluso acceder a los atributos de clase mediante self.__class__.

class Ejemplo:
    def __init__(self):
        self.n = 0  # Atributo de instancia

    def foo(self):
        self.n = 13

¿Cómo llamarlo?

  • Desde fuera de la clase:

    • A través de una instancia de la clase, lo normal:

      inst = Ejemplo()
      inst.foo()
      
    • A través del nombre de la clase, pero pasando una instancia como primer argumento (lo mismo que lo anterior, pero es complicarse sin necesidad):

      inst = Ejemplo()
      Ejemplo.foo(inst)
      
  • Dentro de la clase:

    • Desde otro método de instancia:

      self.foo()
      
    • Desde un método de clase, por poder podría llamarse también usando el argumento cls, pero necesitamos pasar también una instancia válida de la clase:

      cls.foo(inst) # Donde inst = Ejemplo()
      

Método de clase

Están vinculados a la clase misma. Son métodos destinados a alterar el estado de la clase, puede acceder y alterar atributos de clase. Como primer argumento recibe la propia clase, por convención denotado con cls. Recordar que cuando se altera el estado de una clase se altera el estado de todas sus instancias.

class Ejemplo:
    n = 0  # Atributo de clase

    @classmethod 
    def foo(cls):
        cls.n = 13



inst = Ejemplo()  # Instancia 1
inst2 = Ejemplo() # Instancia 2
inst.foo()
print(inst2.n) # 3 (alterado estado de la clase, se propaga a todas las instancias)

¿Cómo llamarlo?

  • Desde fuera de la clase:

    • A través del nombre de la clase, lo normal:

      Ejemplo.foo()
      
    • A través de una instancia de la clase (se puede, pero mejor evitarlo por lo general. Normalmente, cuando se necesita hacer esto es que no necesitamos un método de clase realmente):

      inst = Ejemplo()
      inst.foo()
      
  • Dentro de la clase (además de las opciones anteriores):

    • Desde otro método de clase:

      cls.foo()
      
    • Desde un método de instancia:

      self.foo()
      

Método estático

Son métodos que no están vinculados ni a la clase ni a sus instancias realmente. Un método estático es en realidad una función que definimos dentro de la clase solo porque está relacionado conceptualmente con la misma. No altera el estado de la clase ni de las instancias de la misma, por lo que no modifica atributos de clase o instancia y por tanto no recibe como primer argumento ni la clase propiamente dicha ni una instancia de la misma. Para crearlos se decoran con @stactimethod.

class Ejemplo:
    @staticmethod
    def foo():
        print("Hola")

¿Cómo llamarlo?

  • Desde fuera de la clase:

    • A través de una instancia de la clase:

      inst = Ejemplo()
      inst.foo()
      
    • A través del nombre de la clase:

      inst = Ejemplo()
      Ejemplo.foo()
      
  • Dentro de la clase podemos hacerlo también mediante:

    • Desde otro método de instancia:

      self.foo()
      
    • Desde un método de clase :

      cls.foo()
      

Función definida dentro de una clase

En tu ejemplo, es esto lo que tienes en realidad, una función definida dentro del espacio de nombres de una clase.

class Ejemplo:
    def foo():
        print("Hola")

básicamente es igual que si la definimos fuera de la clase, excepto porque está delimitada por el espacio de nombres de la misma. En realidad es muy parecido a un método estático, solo que no podremos usar la instancia para llamarlo, por lo que tampoco hacer self.foo() desde dentro de la clase.

¿Cómo llamarlo?

  • Desde fuera de la clase, a través del nombre de la clase:

        Ejemplo.foo()
    
  • Dentro de la clase:

    • Desde otro método de instancia haciendo referencia al nombre de la clase solamente:

      Ejemplo.foo()
      self.__class__.foo()
      
    • Desde un método de clase podemos hacer también:

      cls.foo()
      

Relacionado: Diferencia entre atributos de instancia y atributos de clase

FJSevilla
  • 55,603
  • 7
  • 35
  • 58
4

Muy simple:

class AAA:
    def aaa1():
        print ('aaa1')

    def aaa2():
        return 'Soy aaa2'

class BBB:

    def bbb1():
        return AAA.aaa2()

    def bbb2():
        print ('bbb2')


print(BBB.bbb1())
  • La clase AAA tiene un método llamado aaa2() que retorna un valor.
  • La Clase BBB tiene un método llamado bbb1() que llama al al clase AAA , método aaa2() es decir AAA.aaa2() y retorna su valor
  • La clase BBB tiene un método bbb1() que retorna lo que hay en AAA.aaa2() ¿ Es lo que necesitas?
Eduardo Munizaga
  • 2,694
  • 1
  • 13
  • 34
  • la cuestión es que estoy haciendo un árbol de decision y estaba complicándome mil la vida!!!!! Estaba asignando la clase a una variable y luego pasándole a esa variable el método... y claro, me ejecutaba todo no solo el método que yo deseaba. Muchas gracias – Eva Rentero Apr 26 '19 at 13:20
1

Si es desde diferentes lugares de tu proyecto

from directorio.miarchivo import MiClase

newClass = myClass(5)
val = newClass.getVal()
Cristian
  • 95
  • 11