2012-02-12 14 views
7

¿Dónde está el código fuente del decorador classmethod ubicado en el código fuente de python? Específicamente estoy teniendo problemas para encontrar el archivo exacto que está definido en la versión 2.7.2Ubicación de @classmethod

Respuesta

11

yo no estoy respondiendo a lo que usted pidió - pero a continuación muestra lo que podría ser un decorador equivalente a classmethod, escrito en Python puro - ya que la uno en el código fuente está en C, dentro de Python-2.7.2/Objects/funcobject.c como Mishna pone en su respuesta.

Entonces, la idea de los métodos de clase es usar el mecanismo "descriptor", como se describe en Python's data model - y hacer que el método __get__ devuelva un objeto de función que cuando se llame invocará el método original con el primero argumento precargada:

class myclassmethod(object): 
    def __init__(self, method): 
     self.method = method 
    def __get__(self, instance, cls): 
     return lambda *args, **kw: self.method(cls, *args, **kw) 

Y en Python consola:

>>> class MyClass(object): 
...  @myclassmethod 
...  def method(cls): 
...   print cls 
... 
>>> 
>>> m = MyClass() 
>>> m.method() 
<class '__main__.MyClass'> 
>>> 

* EDITAR - actualización *

El O.P. preguntó además "Si quería que el decorador también aceptara un parámetro, ¿cuál sería el formato adecuado para init? "-

En ese caso, no solo es __init__ lo que debe cambiarse: un decorador que acepta parámetros de configuración se llama en realidad en" dos etapas ": el primero anota los parámetros y devuelve un llamante: la segunda llamada acepta sólo la función que efectivamente se adorna

Hay algunas maneras de hacerlo - pero creo que la más sencilla es tener una función que devuelve la clase anterior, como en:.

def myclasmethod(par1, par2, ...): 
    class _myclassmethod(object): 
     def __init__(self, method): 
      self.method = method 
     def __get__(self, instance, cls): 
      # make use of par1, par2,... variables here at will 
      return lambda *args, **kw: self.method(cls, *args, **kw) 
    return _myclassmethod 
+1

si quería que el decorador también aceptara un para meter ¿cuál sería el formato adecuado para init? – user1200501

+0

se puede \ _ \ _ llamar \ _ \ _ en lugar de \ _ \ _ obtener \ _ \ _? – DiogoNeves

+0

bien, después de leer un poco sobre descripciones tiene sentido ahora :) – DiogoNeves

9
tar -zxf Python-2.7.2.tgz 
vim Python-2.7.2/Objects/funcobject.c 

... 
589 /* Class method object */ 
590 
591 /* A class method receives the class as implicit first argument, 
592 just like an instance method receives the instance. 
593 To declare a class method, use this idiom: 
594 
595  class C: 
596  def f(cls, arg1, arg2, ...): ... 
597  f = classmethod(f) 
598 
599 It can be called either on the class (e.g. C.f()) or on an instance 
600 (e.g. C().f()); the instance is ignored except for its class. 
601 If a class method is called for a derived class, the derived class 
602 object is passed as the implied first argument. 
603 
604 Class methods are different than C++ or Java static methods. 
605 If you want those, see static methods below. 
606 */ 
... 
+0

Gracias para la ubicación correcta de la clase – user1200501