2011-07-27 9 views
10

Me preguntaba si utiliza @staticmethod decorator en su código.¿Hay algún beneficio de usar un método @static?

Personalmente no lo uso, ya que se necesitan más letras para escribir @staticmethod luego de uno mismo.

El único beneficio (que se me ocurre) de su uso puede ser una mayor claridad de un código, pero dado que generalmente escribo una descripción de método para sphinx, siempre indico si un método está utilizando o no el objeto.

O tal vez debería empezar a usar @staticmethod decorator?

+0

En realidad, todavía estoy confundido: ¿Hay algunos lugares en los que tengamos que usar métodos estáticos en python3? Encuentro que en muchos lugares no es necesario usar métodos estáticos. –

Respuesta

28

El uso de @staticmethod o no depende de lo que desee lograr. Ignorar al decorador porque hay más que escribir es una razón bastante tonta (¡sin ofender!) E indica que no has entendido el concepto de un método estático en Python.

Los métodos estáticos son independientes de la clase y de cualquier instancia de clase. Solo usan el alcance de la clase como espacio de nombres. Si omite el decorador @staticmethod, está creando un método de instancia que no se puede usar sin construir una instancia.

Aquí es una clase muy simple Foo:

>>> class Foo(object): 
... @staticmethod 
... def foo(): 
...  print 'foo' 
... 
... def bar(self): 
...  print 'bar' 

Ahora, Foo.foo() es un método estático que se puede llamar directamente:

>>> Foo.foo() 
foo 

Foo.bar() por el contrario es un método ejemplo , que solo se puede invocar desde instancias (objetos) de Foo:

>>> Foo.bar() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead) 
>>> foo = Foo() 
>>> foo.bar() 
bar 

Para responder a su pregunta: Si desea definir un método estático, use @staticmethod. De lo contrario, no.

Si usted tiene un método que no utiliza self, y por lo tanto podría escribirse como un método estático, se pregunta: ¿Alguna vez desee acceder a esta función desde fuera sin tener una instancia? La mayoría de las veces, la respuesta será: No.

+5

+1: "Ignorar al decorador porque hay más que escribir es una razón bastante tonta". Suelta la disculpa. Es tonto –

+2

Solo para agregar una razón más para usar el método estático en lugar de uno mismo, no solo para python, sino también para los futuros mantenedores. Destaca que "esta función no depende del estado de la clase O de una instancia", a diferencia de classmethod o un método no decorado. Para un mantenedor que no esté familiarizado con el código (p. Ej .: usted, 5 años a partir de ahora), esto hace que el aprendizaje de la base de código sea mucho más rápido. –

+2

Gracias por su respuesta, ahora que lo veo es una razón realmente tonta :) Todavía tengo mucho que aprender, pero gracias a ustedes, aprender no es tan doloroso como solía ser. – Michal

0

@staticmethod decorador le ahorra tipeo y mejora la legibilidad.

class Example: 
    @staticmethod 
    def some_method(): 
     return 

es lo mismo que:

class Example: 
    def some_method(): 
     return 
    some_method = staticmethod(some_method) 

Creo que puede ser confundido acerca de lo que es un método estático en Python como la terminología difiere de otros idiomas. Un método regular está "vinculado" a la instancia (self), un método de clase está "vinculado" a la clase (cls) mientras que un método estático no está "vinculado" en absoluto (y no puede acceder a los atributos de instancia ni clase.

Ver:

0

Supongamos que queremos definir abs método en la clase Math, entonces tenemos dos opciones:

class Math(): 
    def abs(n): 
     if n>0: 
      return n 
     else: 
      return -n 

class Math2(): 
    @staticmethod 
    def abs(n): 
     if n>0: 
      return n 
     else: 
      return -n 

En python2: toma

>>> Math.abs(-2) 
TypeError: unbound method abs() must be called with Math instance as 
first argument (got int instance instead) 

>>>Math().abs(-2) 
TypeError: abs() takes exactly 1 argument (2 given) 

>>> Math2.abs(-2) 
2 

>>> Math2().abs(-2) 
2 

python2 automáticamente Math().abs(-2) como Math().abs(self,-2), de manera que usted tiene que utilizar @staticmethod.

En python3

>>>Math.abs(-3) 
3 

>>>Math().abs(-3) 
TypeError: abs() takes 1 positional argument but 2 were given 

>>>Math2.abs(-3) 
3 

>>>Math2().abs(-3) 
3 

En python3, puede utilizar classname.method() sin método estático, sino que aumentará TypeError cuando alguien intenta utilizar instance.method().

+0

esta diferente entre python2 y python3 me confunde mucho. –

Cuestiones relacionadas