Domanda

ho qualche codice che ho sviluppato in Python 2.4 ++ e scommettere, devo ad un backport, a Python 2.1!

decoratori funzione erano così attraente che ho usato @classmethod a pochi punti, senza prendere atto del fatto che è disponibile solo a partire da versione 2.4. la stessa funzionalità è offerta da modificatori di funzione, ma questi è apparso in Python 2.2. CFR: http://www.python.org/dev/peps/pep-0318 /

ora alcuni dei nostri clienti sembrano essere ancora dipendente Python 2.1 (ArcGIS 9.1 fornito con esso e rende non aggiornabile), dove nemmeno i modificatori di funzione sono disponibili ...

Sono stato a guardare per alcune definizioni di funzioni di modifica in python 2.1, ma non ho trovato alcun (intendo: di lavoro). nessuno ha risolto con successo il problema?

per essere più concreti, ho bisogno di un modo per eseguire questo codice in 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
>>> 
È stato utile?

Soluzione

Proprio come nella mia vecchia ricetta per 2,1 staticmethod:

class staticmethod:
    def __init__(self, thefunc): self.f = thefunc
    def __call__(self, *a, **k): return self.f(*a, **k)

si dovrebbe essere in grado di fare una classmethod 2.1 come:

class classmethod:
    def __init__(self, thefunc): self.f = thefunc
    def __call__(self, obj, *a, **k): return self.f(obj.__class__, *a, **k)

No @-sintassi, ovviamente, ma piuttosto il modo vecchio (come in 2.2):

class sic:
  def f(cls): ...
  f = classmethod(f)

Se questo non funziona (mi dispiace, è stato molti anni da quando ho avuto un Python 2.1 intorno alla prova), dovrà essere fornito in modo più esplicito la classe - e dal momento che si chiama classmethod prima che l'oggetto esiste classe, dovranno essere per nome - assumendo una classe globale,

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')

E 'davvero difficile trovare il modo elegante per ottenere l'oggetto della classe (sopprimendo la necessità di sé è la parte facile, e ciò che è sufficiente per staticmethod: basta avvolgere la funzione in un non-funzione callable) dal 2.1 aveva solo legacy (classi vecchio stile), non metaclassi utilizzabili, e quindi non realmente buon modo per avere sic2.f () magicamente ottenere che cls.

Dal momento che la mancanza di @ sintassi nel 2.1 richiede inevitabilmente la modifica del codice che utilizza @classmethod, in alternativa è quello di spostare la funzionalità (decorare alcuni metodi di essere "di classe" quelli) a destra dopo la fine della dichiarazione class (il vantaggio è che l'oggetto di classe esiste in quel 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'])

Altri suggerimenti

Se solo il @classmethod bisogno di essere backport a Python 2.1.
C'è un ricetta di emulazione classmethod in python2.1
Spero che questo aiuto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top