@staticmethod vs función de nivel de módulo

21

Esto no se trata de @staticmethody @classmethod! Se como staticmethodfunciona. Lo que quiero saber es los casos de uso adecuados para @staticmethoduna función a nivel de módulo.

Busqué en Google esta pregunta, y parece que hay un acuerdo general de que las funciones de nivel de módulo son preferibles a los métodos estáticos porque es más pitónico. Los métodos estáticos tienen la ventaja de estar vinculados a su clase, lo que puede tener sentido si solo esa clase lo usa. Sin embargo, en Python la funcionalidad generalmente está organizada por módulo, no por clase, por lo que también tiene sentido hacerlo una función de módulo.

Los métodos estáticos también pueden ser anulados por subclases, lo cual es una ventaja o desventaja dependiendo de cómo se mire. Sin embargo, los métodos estáticos suelen ser "funcionalmente puros", por lo que, en general, puede no ser inteligente, pero a veces puede ser conveniente (aunque este puede ser uno de esos "convenientes, pero NUNCA LO HAGA" cosas que solo la experiencia puede enseñarle).

¿Existe alguna regla general para usar el método estático o las funciones a nivel de módulo? ¿Qué ventajas o desventajas concretas tienen (por ejemplo, extensión futura, extensión externa, legibilidad)? Si es posible, también proporcione un ejemplo de caso.

darkfeline
fuente

Respuestas:

11

Técnicamente, un método estático y una función de módulo se comportan de manera casi idéntica: en ambos casos funcionan como funciones estándar, la diferencia es el espacio de nombres donde se ubican. Entonces, la decisión es más de mantenibilidad / legibilidad.

En general, usaría un método estático si se cumplen algunos o todos estos criterios:

  • Ya existe una clase con métodos normales.
  • La función se relaciona con objetos de la clase en general, pero no con una instancia específica.
  • Desea poder llamar al método como si fuera un método no estático, posiblemente porque puede querer que el método no sea estático en el futuro sin romper el código del cliente
Michael Slade
fuente
0

Un programa es una simulación de una realidad. De esta manera, depende de cómo percibas la realidad.

Una función representa alguna actividad. Cuanto más general es la actividad, mayor es la tendencia a simular la actividad con una función. Los métodos están vinculados a las clases. Cuanto más específica es la actividad de la clase, más tiende a simularse mediante un método.

Piensa en las funciones trigonométricas. Digamos que sin()es tan conocido que sabes que encaja con los ángulos. Usted sabe que quiere un número flotante como entrada y devuelve el flotante. De todos modos, puede haber un tipo de datos de ángulo representado por una clase y el .sin()argumento sin podría ser un método normal que funcione con el objeto de ángulo, y .sin(x)con un solo argumento podría ser un método estático de la clase. Podría apostar que más personas piensan que es mejor hacer sin()una función simple. Están más acostumbrados.

Otro punto de vista : un módulo se asemeja a una instancia de clase. Tiene sus propias variables miembro y funciones miembro. En cierto sentido, implementa un patrón singleton. Cada vez que lo importa desde otro módulo de la aplicación, obtiene acceso a exactamente las mismas variables y funciones.

pepr
fuente
0

Tengo una función que tomará parte de la jerarquía de datos profundos de un objeto como argumento. Sería engorroso pasar los diversos argumentos necesarios para llegar a esa parte de la jerarquía de datos. Por lo tanto, no tiene motivos para hacer referencia a uno mismo o cls. Pero la funcionalidad solo se utilizará en partes de objetos de una clase en particular. Entonces me parece un método de clase.

Además, prefiero importar el nombre de la clase ('desde la clase de importación del módulo' en lugar de 'importar el módulo'). Incluir la función como método estático me da acceso al método mientras que escribirlo como una función a nivel de módulo requeriría una importación diferente.

DVD Avins
fuente
2
Si yo fuera tú, evitaría responder en primera persona. Es confuso. En su lugar, debe escribir en segunda persona al autor de la pregunta.
Aaron Hall
Quizás. Estaba proporcionando un ejemplo de caso de uso, que puede coincidir o no con lo que el autor de la pregunta tenía en mente.
Dvd Avins