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?
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?
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?
Relacionado: Diferencia entre atributos de instancia y atributos de clase