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
>>> 
¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top