就像我在 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)
没有@
-syntax 当然,而是旧的方式(如在 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 的需要是容易的部分,而静态方法就足够了:你只需要将函数包装成非函数可调用),因为 2.1 只有遗留(旧-style 类),没有可用的元类,因此没有真正好的方法让 sic2.f() 神奇地获得那个 cls。
由于 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'])