2012-04-30 28 views
21

Una vez leí (creo que en una página de Microsoft) que es una buena forma de usar clases estáticas, cuando NO NECESITA dos o más instancias de una clase.Clases estáticas en Python

Estoy escribiendo un programa en Python. ¿Es un mal estilo si uso @classmethod para cada método de una clase?

Respuesta

6

En mi experiencia la creación de una clase es una muy buena solución por una serie de razones. Una de ellas es que terminas usando la clase como una clase "normal" (especialmente haciendo más de una instancia) más a menudo de lo que piensas. También es una opción de estilo razonable seguir las clases para todo; esto puede hacer que sea más fácil para otras personas que leen/mantienen su código, especialmente si son muy OO, se sentirán cómodos con las clases. Como se indicó en otras respuestas, también es razonable usar funciones "simples" para la implementación. Es posible que desee comenzar con una clase y convertirla en un patrón singleton/Borg (muchos ejemplos si utiliza googlefor estos); le da flexibilidad para (re) usar la clase para satisfacer otras necesidades. Recomendaría contra el enfoque de "clase estática" como no convencional y no-Pitónico, lo que hace que sea más difícil de leer y mantener.

+7

La mayor parte de su respuesta, siendo las excepciones principales la segunda y la última oración, es discutible (y tiendo a estar en desacuerdo) y además del punto. Yo diría que cortar toda la pelusa sobre cómo las grandes clases lo mejorarían, ¿qué piensas? – delnan

+0

Estoy de acuerdo y en desacuerdo con esta respuesta al mismo tiempo. Así que no puedo decidir si presionar el botón hacia arriba o hacia abajo. De todos modos, estoy de acuerdo con los Objetos que hacen que el código sea más fácil de leer y mantener. No estoy de acuerdo con el uso del patrón singleton/borg http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Singleton.html. No es que sea un mal patrón; sin embargo, usar métodos estáticos con variables de clase es mucho más fácil de mantener y leer en un proyecto de código extremadamente complicado. Sí, esto puede no ser técnicamente correcto, pero los programadores de nivel junior te lo agradecerán. –

27

En general, el uso de este tipo se realiza mejor simplemente mediante el uso de funciones en un módulo, sin una clase en absoluto.

+8

+1. Absolutamente no es necesario crear una clase en Python si no está encapsulando ningún dato. –

+1

A veces empiezo con funciones simples, pero luego me doy cuenta de que, como me gusta escribir pequeñas funciones, a veces tengo que pasar el mismo parámetro entre 3 o 4 de ellas, en cuyo punto empiezo a querer encapsular ese parámetro. Todavía tengo que resolver este enigma. ¿Pensamientos? – Leonid

+0

@Leonid Yo diría que si sus funciones son independientes pero aún quieren los parámetros entre ellas, simplemente pase esos parámetros. Si encuentra que tiene muchas llamadas con las mismas colecciones de paramteres, tal vez produzca un 'namedtuple' o algo por lo que pueda pasar. Almacenar cosas en una clase solo para evitar pasarlas es generalmente una mala idea de todos modos, podría generar problemas. –

13

Es un estilo terrible, a menos que realmente necesite acceder a la clase.

Un método estático [...] no se traduce en un método de clase Python. Oh, claro, da como resultado más o menos el mismo efecto, pero el objetivo de un método de clase es hacer algo que ni siquiera es posible [...] (como heredar un constructor no predeterminado). La traducción idiomática de un método [...] estático suele ser una función a nivel de módulo, no un método de clase o estático.

source

6

Hay algunos enfoques que puede tomar para esto. Como otros lo han mencionado, puedes usar funciones de nivel de módulo. En este caso, el módulo en sí es el espacio de nombres que los mantiene juntos. Otra opción, que puede ser útil si necesita realizar un seguimiento del estado, es definir una clase con métodos normales (tomando self), y luego definir una única instancia global de la misma y copiar sus métodos de instancia al espacio de nombres del módulo. Este es el enfoque adoptado por el módulo "aleatorio" de la biblioteca estándar: echa un vistazo a lib/python2.5/random.py en tu directorio python. En la parte inferior, que tiene algo como esto:

# Create one instance, seeded from current time, and export its methods 
# as module-level functions. [...] 
_inst = Random() 
seed = _inst.seed 
random = _inst.random 
uniform = _inst.uniform 
... 

o puede tomar el enfoque básico que ha descrito (aunque yo recomendaría usar @staticmethod en lugar de @classmethod en la mayoría de los casos).

Cuestiones relacionadas