Question

J'ai un code j'ai développé en Python 2.4 ++ et que vous misez, je dois le rétroporter à python 2.1!

décorateurs de fonction étaient si attrayante que je l'ai utilisé @classmethod à quelques endroits, sans tenir compte du fait qu'il est disponible à partir de la version 2.4. la même fonctionnalité est proposée par des modificateurs de fonction, mais ceux-ci est apparu en python 2.2. cfr: http://www.python.org/dev/peps/pep-0318 /

maintenant certains de nos clients semblent dépendre encore Python 2.1 (ArcGIS 9.1 est livré avec et le rend pas upgradable), où même les modificateurs de fonction sont disponibles ...

J'ai cherché quelques définitions de modification de la fonction en Python 2.1, mais je ne ai trouvé aucun (je veux dire: le travail). tout le monde a résolu avec succès ce problème?

pour être plus concret, je besoin d'un moyen d'exécuter ce code 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
>>> 
Était-ce utile?

La solution

Tout comme dans ma vieille recette de 2,1 staticmethod:

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

vous devriez être en mesure de faire un 2.1 classmethod comme:

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

Non @-syntaxe bien sûr, mais plutôt à l'ancienne (comme dans 2.2):

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

Si cela ne fonctionne pas (désolé, depuis de nombreuses années que j'ai eu un Python 2.1 autour de tester), la classe devra être fournie de manière plus explicite - et que vous appelez classmethod avant que l'objet existe pour une classe, il devront être par son nom - en supposant une classe mondiale,

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

Il est vraiment difficile de trouver des façons élégantes pour obtenir l'objet de classe (en supprimant le besoin d'auto est la partie facile, et ce qui suffit pour staticmethod: il vous suffit d'envelopper la fonction dans une non-fonction appelable) depuis 2.1 avait seulement (héritage des classes de style ancien), pas métaclasses utilisables, et donc pas très bon moyen d'avoir sic2.f () obtenir par magie que le CCRS.

Depuis l'absence de syntaxe @ en 2.1 nécessite inévitablement l'édition de code qui utilise @classmethod, une alternative est de déplacer la fonctionnalité (décoration des méthodes pour être les « classes ») à droite après la fin de la déclaration de class (l'avantage est que l'objet de la classe existe à ce moment-là).

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

Autres conseils

Si seulement le @classmethod doivent être rétroportés à Python 2.1.
Il y a un recette d'émulation classmethod à python2.1
Espérons que cela aide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top