Creo que Steven tiene razón. Entonces, para responder a la pregunta original, para configurar un método de clase, simplemente asuma que el primer argumento no será una instancia de llamada, y luego asegúrese de llamar al método solo desde la clase.
(Tenga en cuenta que esta respuesta se refiere a Python 3.x. En Python 2.x obtendrá un TypeError
para llamar al método en la propia clase).
Por ejemplo:
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
def rollCall(n): #this is implicitly a class method (see comments below)
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
En este código, el método «rollCall» asume que el primer argumento no es una instancia (como sería si fuera llamado por una instancia en lugar de una clase). Siempre que se llame a «rollCall» desde la clase en lugar de una instancia, el código funcionará bien. Si intentamos llamar a «rollCall» desde una instancia, por ejemplo:
rex.rollCall(-1)
sin embargo, provocaría la aparición de una excepción porque enviaría dos argumentos: él mismo y -1, y «rollCall» solo está definido para aceptar un argumento.
Por cierto, rex.rollCall () enviaría el número correcto de argumentos, pero también provocaría una excepción porque ahora n representaría una instancia de Dog (es decir, rex) cuando la función espera que n sea numérico.
Aquí es donde entra la decoración: si precedemos al método «rollCall» con
@staticmethod
luego, al indicar explícitamente que el método es estático, incluso podemos llamarlo desde una instancia. Ahora,
rex.rollCall(-1)
trabajaría. La inserción de @staticmethod antes de la definición de un método, entonces, evita que una instancia se envíe a sí misma como un argumento.
Puede verificar esto probando el siguiente código con y sin la línea @staticmethod comentada.
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
@staticmethod
def rollCall(n):
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
rex.rollCall(-1)