2016-11-07 7 views
0

私は200k LOCのPython 2.3ベースの大きなインストールを持っています。マイグレーションプロジェクトの一環として、すべての古いスタイルのクラスのすべての属性ルックアップをインターセプトする必要があります。Python 2.3の古いスタイルのmixinクラスで__getattr__を傍受していますか?

古いレガシーコード:

class Foo(Bar): 
    ... 

私の考えはFoo.__getattr__Mixin.__getattr__に を解決するために、私は再帰に常に実行していますが

class Foo(Bar, Mixin): 
    ... 

class Mixin: 

    def __getattr__(self, k) 
     print repr(self), k 
     return Foo.__getattr__(self, k) 

のような一般的なミックスインクラスを注入することです。

Python 2.3の古いスタイルのクラスのコードを修正する方法はありますか?

+0

古いスタイルのクラスは既に '__getattr__'を実装していますか? – donkopotamus

+0

もちろん、__getattribute __()は新しいスタイルのクラスで導入されました –

+0

ミックスインを追加して '__getattr__'を実装する前に**あなたのコードベース**に古いスタイルのクラス**を追加することを意味します** – donkopotamus

答えて

0

あなたはすでに、なぜそれらの新しいスタイル

class Foo(Mixin, Bar, object): 
    ... 

作るために、親としてobjectを追加して、あなたのコード内のクラスのいずれもがないと仮定するとsuper

class Mixin(object): 

    def __getattr__(self, k) 
     print repr(self), k 
     return super(Mixin, self).__getattr__(k) 
+0

適切ではありません。私は数百のクラスを、すべてとすべてを壊さずに新しいスタイルのクラスに変えることはできません(異なる継承など)。 –

+0

Mixinsは古いスタイルのクラスには適していません。なぜなら「コール - 親」機能がなかったからです。あなたは 'return bar 'を呼び出すことができます。__getattr __(self、k) 'を手動で実行しますが、これは' Foo'クラスの問題だけを修正します。 –

+0

これは当てはまりません。 Zope 2のコードベースでは、1999年以来mixinsが広く使用されています –

0

を使用しないで、ミックスインを注入している場合__setattr__または__getattr__の場合は、ミックスインの__setattr__を傍受して別の予約済み属性に値を書き込み、__getattr__

class Mixin: 
    def __setattr__(self, attr, value): 
     # write the value into some special reserved space 
     namespace = self.__dict__.setdefault("_namespace", {}) 
     namespace[attr] = value 

    def __getattr__(self, attr): 
     # reject special methods so e.g. __repr__ can't recurse 
     if attr.startswith("__") and attr.endswith("__"): 
      raise AttributeError 

     # do whatever you wish to do here ... 
     print repr(self), attr 

     # read the value from the reserved space 
     namespace = self.__dict__.get("_namespace", {}) 
     return namespace[attr] 

例:

class Foo(Mixin): 
    def __init__(self): 
     self.x = 1 

その後

>>> Foo().x 
<__main__.Foo instance at 0x10c4dad88> x 

あなたFooクラスのいずれかが__setattr__または__getattr__自体を実装する場合は明らかにこれは動作しません。

+0

オブジェクトのインスタンスは永続オブジェクト(ZODB)の観点から存在するので、いいアイデアですが、まだうまくいきません。だからあなたの__setattr __()が関与していなかったのでチャンスはありません –

+0

あなたの質問に含まれるクラスのタイプについていくつかの詳細を述べてください...もしそれらがzopeであれば、それは潜在的な解決策に関連します。 – donkopotamus

+0

例えば、これらのクラスのすべてがZODB永続化されている場合、潜在的な解決策は、データベースからロードされたオブジェクトがパッチされたzope基本クラスを使用するように、 – donkopotamus

関連する問題