Frage

Ich habe einen Code, den ich in Python 2.4 ++ entwickelt habe, und Sie wetten, ich muss ihn auf Python 2.1 zurückführen!

Funktionsdekoratoren waren so attraktiv, dass ich @ClassMethod an einigen Stellen verwendet habe, ohne dass es ab Version 2.4 nur verfügbar ist. Die gleiche Funktionalität wird von Funktionsmodifikatoren angeboten, diese erschienen jedoch in Python 2.2. CFR: http://www.python.org/dev/peps/pep-0318/

Jetzt scheinen einige unserer Kunden immer noch von Python 2.1 abhängig zu sein (ArcGIS 9.1 wird damit versandt und macht es nicht aktualisierbar), wo nicht einmal die Funktionsmodifikatoren verfügbar sind ...

Ich habe nach einigen Funktionsmodifikator -Definitionen in Python 2.1 gesucht, aber ich habe keine gefunden (ich meine: Arbeiten). Hat jemand dieses Problem erfolgreich gelöst?

Um konkreter zu sein, brauche ich eine Möglichkeit, diesen 2.4 -Code in Python 2.1 auszuführen:

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
>>> 
War es hilfreich?

Lösung

Genau wie in meinem alten Rezept für 2.1 staticMethod:

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

Sie sollten in der Lage sein, einen 2.1 ClassMethod als:

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

Nein @-Syntax natürlich, sondern vielmehr der alte Weg (wie in 2.2):

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

Wenn dies nicht funktioniert (sorry, viele Jahre, seit ich einen Python 2.1 zu testen hatte), muss die Klasse explizit geliefert werden - und da Sie ClassMethod anrufen, bevor das Klassenobjekt existiert mit Namen sein - unter der Annahme einer globalen Klasse,

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 ist wirklich schwierig, elegante Möglichkeiten zu finden, um das Klassenobjekt zu erhalten (das Bedürfnis nach sich selbst zu unterdrücken ist der einfache Teil und was für staticMethod ausreicht: Sie müssen die Funktion nur in einen nicht funktionierenden Anruf einwickeln), da 2.1 nur Vermächtnis hatte (alt -Stilklassen), keine verwendbaren Metaklasse und damit keine wirklich gute Möglichkeit, sic2.f () diese CLS auf magische Weise zu bekommen.

Da das Fehlen von @ syntax in 2.1 unweigerlich die Bearbeitung von Code erfordert, die verwendet @classmethod, Eine Alternative besteht darin, die Funktionalität (einige Methoden so zu dekorieren, dass sie "Klasse" sein) auf direkt nach dem Ende der class Aussage (der Vorteil ist, dass das Klassenobjekt zu diesem Zeitpunkt existiert).

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

Andere Tipps

Wenn nur der @classMethod auf Python 2.1 zurückgebracht werden muss.
Da ist ein Rezept der Klassenmethodenemulation in Python2.1
Ich hoffe das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top