backport função de modificadores para python2.1
Pergunta
Tenho um código desenvolvido em python 2.4++ e pode apostar, eu tenho que adaptar ele para python 2.1!
função decoradores foram tão atraente que eu usei @classmethod em alguns pontos, sem tomando conhecimento do fato de que ele só está disponível a partir da versão 2.4.a mesma funcionalidade é oferecida pela função de modificadores, mas estes apareceu em python 2.2.cfr: http://www.python.org/dev/peps/pep-0318/
agora alguns de nossos clientes parecem ser ainda depende de python 2.1 (ArcGIS 9.1 acompanha-lo e torna-lo não atualizável), onde nem mesmo a função de modificadores estão disponíveis...
Eu estava procurando alguns função de modificador de definições em python 2.1, mas eu não encontrei nenhum (quero dizer:de trabalho).qualquer pessoa com êxito para resolver este problema?
para ser mais concreto, eu preciso de uma maneira de executar essa 2.4 código em python 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
>>>
Solução
Assim como na minha velha receita para 2.1 staticmethod:
class staticmethod:
def __init__(self, thefunc): self.f = thefunc
def __call__(self, *a, **k): return self.f(*a, **k)
você deve ser capaz de fazer um 2.1 classmethod como:
class classmethod:
def __init__(self, thefunc): self.f = thefunc
def __call__(self, obj, *a, **k): return self.f(obj.__class__, *a, **k)
Nenhum @
-sintaxe de curso, mas, sim, a velha forma (como em 2.2):
class sic:
def f(cls): ...
f = classmethod(f)
Se isto não funcionar (desculpe, foi durante muitos anos desde que eu tinha um Python 2.1 volta para teste), a classe precisa ser fornecido de forma mais explícita-e desde que você chamar classmethod antes da classe de objeto existe, ele precisará ser por nome, assumindo uma classe global,
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')
É realmente difícil encontrar elegantes formas de obter o objeto de classe (suprimindo a necessidade de auto-é a parte fácil, e o que é suficiente para staticmethod:você só precisa quebrar a função em uma função não exigível) desde 2.1 só tinha herdado (velho estilo de classes), não utilizável metaclasses, e, portanto, nenhuma realmente boa forma de ter sic2.f() magicamente conseguir que o cls.
Uma vez que a falta de @ sintaxe em 2.1, inevitavelmente, requer a edição de código que usa @classmethod
, uma alternativa é mover a funcionalidade (decorar alguns métodos para ser "classe") para a direita APÓS o final do class
instrução (a vantagem é que o objeto de classe não existia naquela época).
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'])
Outras dicas
Se apenas o @classMethod precisar ser backupled para o Python 2.1.
Existe um Receita de emulação de classe de classe em python2.1
Espero que isso ajude.