python2.1にバックポート機能修飾子
質問
私は2.1をPythonのためにそれをバックポートする必要があり、私は私のpython 2.4 ++で開発されたいくつかのコードを持っていて、賭け!
関数デコレータは、私はそれがバージョン2.4から始まるのみ利用可能であるという事実の通知を取ることなく、いくつかのスポットで@classmethod使用していたほど魅力的でした。同じ機能は、関数修飾子によって提供されているが、これらは、Python 2.2で登場しました。 CFR: http://www.python.org/dev/peps/pep-0318 / の
今、私たちの顧客の一部は、Python 2.1にまだ依存しているように見える(それとのArcGIS 9.1船とそれがないアップグレード可能)、いなくても機能修飾子が利用可能な場合...
私は、Python 2.1でいくつかの機能修飾子の定義を探してきたが、私は(私は意味:作業)いずれかを見つけることができませんでした。誰が正常にこの問題を解決する?
より具体的にするために、私は、Python 2.1で、この2.4のコードを実行するための方法が必要になります:
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
>>>
解決
ただ、2.1 staticmethodのための私の古いレシピのように:
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を持っていたので、申し訳ありませんが、多くの多くの年に)動作しない場合は、、クラスがより明示的に供給する必要があります - とクラスオブジェクトが存在する前に、クラスメソッドを呼び出すので、名前でする必要があります - グローバルクラスを想定し、
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')
2.1しか持っていたので、:それは(あなただけの非機能呼び出し可能に関数をラップする必要が自己の必要性を抑制することは容易な部分であり、そして何staticmethodで十分)クラスオブジェクトを取得するためのエレガントな方法を見つけることは本当に難しいですレガシー(旧スタイルのクラス)、無使用可能なメタクラス、および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'])
他のヒント
ちょうど@classmethodは、Python 2.1にバックポートする必要がある場合。
python2.1 の
でクラスメソッドエミュレーションのレシピがあります
このヘルプを願っています。