daryl spitzer
¿Cuál es la diferencia entre una función decorada con @staticmethod
y uno decorado con @classmethod
?
Tomás Wouters
A método estático es un método que no sabe nada acerca de la clase o instancia a la que fue llamado. Solo obtiene los argumentos que se pasaron, sin un primer argumento implícito. Básicamente es inútil en Python: solo puede usar una función de módulo en lugar de un método estático.
A método de clase, por otro lado, es un método al que se le pasa la clase a la que se llamó, o la clase de la instancia a la que se llamó, como primer argumento. Esto es útil cuando desea que el método sea una fábrica para la clase: dado que obtiene la clase real a la que se invocó como primer argumento, siempre puede instanciar la clase correcta, incluso cuando hay subclases involucradas. Observa por ejemplo cómo dict.fromkeys()
un método de clase, devuelve una instancia de la subclase cuando se llama a una subclase:
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
-
Un método estático no es inútil: es una forma de colocar una función en una clase (porque lógicamente pertenece allí), al tiempo que indica que no requiere acceso a la clase.
– Tony Mayer
26 de septiembre de 2008 a las 10:10
-
Por lo tanto, solo ‘básicamente’ inútil. Dicha organización, así como la inyección de dependencias, son usos válidos de los métodos estáticos, pero dado que los módulos, no las clases como en Java, son los elementos básicos de la organización del código en Python, su uso y utilidad son raros.
– Thomas Wouters
26 de septiembre de 2008 a las 13:40
-
¿Qué tiene de lógico definir un método dentro de una clase, cuando no tiene nada que ver ni con la clase ni con sus instancias?
– Ben James
12 de marzo de 2010 a las 9:11
-
¿Quizás por el bien de la herencia? Los métodos estáticos se pueden heredar y anular al igual que los métodos de instancia y los métodos de clase y la búsqueda funciona como se esperaba (a diferencia de Java). Los métodos estáticos no se resuelven realmente de forma estática, ya sea que se llamen a la clase oa la instancia, por lo que la única diferencia entre la clase y los métodos estáticos es el primer argumento implícito.
– haridsv
8 de abril de 2010 a las 1:32
-
También crean un espacio de nombres más limpio y facilitan la comprensión de que la función tiene algo que ver con la clase.
– Imbordar
22 de agosto de 2011 a las 11:58
du d
Para decidir si usar @métodoestático o @métodoclase tienes que mirar dentro de tu método. Si su método accede a otras variables/métodos en su clase, use @classmethod. Por otro lado, si su método no toca ninguna otra parte de la clase, use @staticmethod.
class Apple:
_counter = 0
@staticmethod
def about_apple():
print('Apple is good for you.')
# note you can still access other member of the class
# but you have to use the class instance
# which is not very nice, because you have repeat yourself
#
# For example:
# @staticmethod
# print('Number of apples have been juiced: %s' % Apple._counter)
#
# @classmethod
# print('Number of apples have been juiced: %s' % cls._counter)
#
# @classmethod is especially useful when you move your function to another class,
# you don't have to rename the referenced class
@classmethod
def make_apple_juice(cls, number_of_apples):
print('Making juice:')
for i in range(number_of_apples):
cls._juice_this(i)
@classmethod
def _juice_this(cls, apple):
print('Juicing apple %d...' % apple)
cls._counter += 1
-
¿Cuál sería la ventaja de classmethod y cls._counter frente a staticmethod y Apple._counter?
– Robert Nowak
11 oct 2019 a las 10:38
-
cls._counter
todavía seríacls._counter
incluso si el código se coloca en una clase diferente o se cambia el nombre de la clase.Apple._counter
es específico para elApple
clase; para una clase diferente, o cuando se cambia el nombre de la clase, deberá cambiar la clase a la que se hace referencia.– apaderno
12 de noviembre de 2019 a las 22:55
yo y
Documentos oficiales de Python:
Un método de clase recibe la clase como primer argumento implícito, al igual que un método de instancia recibe la instancia. Para declarar un método de clase, usa este modismo:
class C: @classmethod def f(cls, arg1, arg2, ...): ...
los
@classmethod
la forma es una funcion
decorador – consulte la descripción de las definiciones de funciones en Definiciones de funciones para detalles.Se puede llamar en la clase (como
C.f()
) o en una instancia (comoC().f()
). La instancia se ignora excepto por su clase. Si se llama a un método de clase para una clase derivada, el objeto de la clase derivada se pasa como el primer argumento implícito.Los métodos de clase son diferentes a los métodos estáticos de C++ o Java. Si quieres esos, mira
staticmethod()
en esta sección.
Un método estático no recibe un primer argumento implícito. Para declarar un método estático, usa este modismo:
class C: @staticmethod def f(arg1, arg2, ...): ...
los
@staticmethod
la forma es una funcion
decorador – consulte la descripción de las definiciones de funciones en Definiciones de funciones para detalles.Se puede llamar en la clase (como
C.f()
) o en una instancia (comoC().f()
). La instancia se ignora excepto por su clase.Los métodos estáticos en Python son similares a los que se encuentran en Java o C++. Para un concepto más avanzado, véase
classmethod()
en esta sección.
-
¿Cuál sería la ventaja de classmethod y cls._counter frente a staticmethod y Apple._counter?
– Robert Nowak
11 oct 2019 a las 10:38
-
cls._counter
todavía seríacls._counter
incluso si el código se coloca en una clase diferente o se cambia el nombre de la clase.Apple._counter
es específico para elApple
clase; para una clase diferente, o cuando se cambia el nombre de la clase, deberá cambiar la clase a la que se hace referencia.– apaderno
12 de noviembre de 2019 a las 22:55
Comunidad
Aquí es un breve artículo sobre esta cuestión
La función @staticmethod no es más que una función definida dentro de una clase. Es invocable sin instanciar la clase primero. Su definición es inmutable a través de la herencia.
La función @classmethod también se puede llamar sin instanciar la clase, pero su definición sigue a la Subclase, no a la clase Padre, a través de la herencia. Eso es porque el primer argumento para la función @classmethod siempre debe ser cls (clase).
-
Entonces, ¿eso significa que al usar un método estático siempre estoy vinculado a la clase principal y con el método de clase estoy vinculado a la clase en la que declaro el método de clase (en este caso, la subclase)?
-Mohan Gulati
3 de noviembre de 2009 a las 19:06
-
No. Al usar un método estático no estás obligado en absoluto; no hay un primer parámetro implícito. Al usar classmethod, obtiene como primer parámetro implícito la clase en la que llamó al método (si lo llamó directamente en una clase), o la clase de la instancia en la que llamó al método (si lo llamó en una instancia).
–Matt Anderson
3 de noviembre de 2009 a las 19:18
-
Podría expandirse un poco para mostrar que, al tener una clase como primer argumento, los métodos de clase tienen acceso directo a otros atributos y métodos de clase, mientras que los métodos estáticos no (necesitarían codificar MyClass.attr para eso)
– Mestre León
3 mayo 2012 a las 10:01
-
“Su definición es inmutable a través de la herencia”. no tiene ningún sentido en Python, puede anular un método estático muy bien.
– cz
17 sep 2019 a las 15:20
Los métodos estáticos a veces son mejores como funciones de nivel de módulo en python por el bien de la limpieza. Con una función de módulo, es más fácil importar solo la función que necesita y evitar “.” innecesarios. sintaxis (te estoy mirando Objective-C). Los métodos de clase tienen más uso ya que se pueden usar en combinación con polimorfismo para crear funciones de “patrón de fábrica”. esto se debe a que los métodos de clase reciben la clase como un parámetro implícito.
– Puño de la furia
6 de diciembre de 2017 a las 3:44
tl; dr >> en comparación con los métodos normales, los métodos estáticos y los métodos de clase también se pueden acceder usando la clase, pero a diferencia de los métodos de clase, los métodos estáticos son inmutables a través de la herencia.
– Sr. Posterior no normalizado
11 de julio de 2018 a las 15:02
Charla relacionada de Raymond Hettinger sobre el tema: youtube.com/watch?v=HTLu2DFOdTg
– mooooooooooooooooooooooo
10 de septiembre de 2018 a las 9:35