modificadores de función backport a python2.1
Pregunta
tengo algo de código que he desarrollado en Python 2.4 ++ y se apuesta, tengo que acondicionarlo tal a Python 2.1!
decoradores de función eran tan atractivas que he utilizado @classmethod en algunos puntos, sin tomar en cuenta el hecho de que sólo está disponible a partir de la versión 2.4. la misma funcionalidad es ofrecida por los modificadores de función pero éstas apareció en Python 2.2. CFR: http://www.python.org/dev/peps/pep-0318 /
Ahora algunos de nuestros clientes parecen ser aún depende de Python 2.1 (ArcGIS 9.1 se envía con él y no lo hace actualizable), donde ni siquiera los modificadores de función están disponibles ...
He estado buscando algunas definiciones modificadoras función en Python 2.1, pero no he encontrado ninguna (quiero decir: el trabajo). nadie resuelto con éxito este problema?
Para ser más concretos, necesito una forma de ejecutar este código en Python 2.4 2.1:
Python 2.4.6 (#2, Mar 19 2009, 10:00:53)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class sic:
... def f(cls):
... print cls.__name__
... f = classmethod(f)
...
>>> sic().f()
sic
>>> sic.f()
sic
>>>
Solución
Al igual que en mi vieja receta de 2.1 métodoestático:
class staticmethod:
def __init__(self, thefunc): self.f = thefunc
def __call__(self, *a, **k): return self.f(*a, **k)
usted debe ser capaz de hacer un classmethod 2.1 como:
class classmethod:
def __init__(self, thefunc): self.f = thefunc
def __call__(self, obj, *a, **k): return self.f(obj.__class__, *a, **k)
No se @
-sintaxis, por supuesto, sino más bien a la antigua (como en 2.2):
class sic:
def f(cls): ...
f = classmethod(f)
Si esto no funciona (lo siento, ha sido muchos años ya que tenía un Python 2.1 en torno a probar), tendrá que ser suministrado de manera más explícita la clase - y puesto que usted llama classmethod antes de que exista la clase de objeto, se tendrá que ser por su nombre - asumiendo una clase mundial,
class classmethod2:
def __init__(self, thefunc, clsnam):
self.f = thefunc
self.clsnam = clsnam
def __call__(self, *a, **k):
klass = globals()[self.clsnam]
return self.f(klass, *a, **k)
class sic2:
def f(cls): ...
f = classmethod2(f, 'sic2')
Es muy difícil encontrar la manera elegante de conseguir el objeto de clase (suprimiendo la necesidad de auto es la parte fácil, y lo que es suficiente para métodoestático: sólo tiene que englobar la función en un no-función exigible) desde la versión 2.1 sólo tenía legacy (clases de estilo antiguo), no hay metaclases utilizables, y por lo tanto no muy buena manera de tener sic2.f () mágicamente conseguir que la CLS.
Desde la falta de @ sintaxis en 2.1 requiere inevitablemente de edición de código que utiliza @classmethod
, una alternativa es mover la funcionalidad (la decoración de algunos métodos que los "clase") a la derecha después del final de la instrucción class
(la ventaja es que el objeto de clase existe en ese momento).
class classmethod3:
def __init__(self, thefunc, klass):
self.f = thefunc
self.klass = klass
def __call__(self, *a, **k):
return self.f(self.klass, *a, **k)
def decorate(klass, klassmethodnames):
for n in klassmethodnames:
thefunc = klass.__dict__[n]
setattr(klass, n, classmethod3(thefunc, klass))
class sic2:
def f(cls): ...
def g(self): ...
def h(cls): ...
decorate(sic2, ['f', 'h'])
Otros consejos
Si sólo el @classmethod necesita ser portado a Python 2.1.
Hay una receta de la emulación classmethod en python2.1
Espero que esta ayuda.