modificatori di funzione backport a python2.1
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
>>>
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.