Так же, как в моем старом рецепте для статического метода 2.1:
class staticmethod:
def __init__(self, thefunc): self.f = thefunc
def __call__(self, *a, **k): return self.f(*a, **k)
Вы должны быть в состоянии сделать метод класса 2.1 как:
class classmethod:
def __init__(self, thefunc): self.f = thefunc
def __call__(self, obj, *a, **k): return self.f(obj.__class__, *a, **k)
Нет @
-синтаксис конечно, а скорее старый (как в 2.2):
class sic:
def f(cls): ...
f = classmethod(f)
Если это не сработает (извините, прошло много лет с тех пор, как у меня был Python 2.1 для тестирования), класс нужно будет предоставить более явно - и поскольку вы вызываете classmethod до того, как объект класса существует, он нужно будет по имени - при условии глобального класса,
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')
Действительно трудно найти элегантные способы получить объект класса (подавление потребности в self - это простая часть, и того, что достаточно для staticmethod: вам просто нужно обернуть функцию в не вызываемый функцией), поскольку в 2.1 было только наследие (классы старого стиля), нет пригодных для использования метаклассов и, следовательно, нет действительно хорошего способа, чтобы sic2.f () волшебным образом получала этот класс.
Поскольку отсутствие синтаксиса @ в 2.1 неизбежно требует редактирования кода, использующего @classmethod
, альтернативой является перемещение функциональности (декорируя некоторые методы как «классовые») вправо ПОСЛЕ конца class
оператор (преимущество в том, что объект класса существует в то время).
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'])