2

基本的に、次のような多くの Python クラス (データベース スキーマを表す) があります。

from foo import xyz, b, c

class bar(object):
    x = xyz()
    y = b()
    z = c()

...そして、これを次のように変更します。

from foo import b, c
from baz import foobar

class bar(object):
    x = foobar()
    y = b()
    z = c()

xyz基本的に、すべてのインスタンスをに置き換えたいだけですfoobar。a のインポートをそのままにしておくことは許容されるので、これでも問題ありません。

from foo import a, b, c
from baz import foobar

class bar(object):
    x = foobar()
    y = b()
    z = c()

これを行うのは簡単なことのように思えますsed s/xyz/foobar/が、それでも戻って import ステートメントを変更する必要があります。多少の手作業は問題ありませんが、その量を最小限に抑える新しい方法を学びたいです。

では、この変更をどのように行いますか?これを行うためにsedでできることはありますか?またはロープ(ここで私を助ける明らかなものは何もありません)?

4

5 に答える 5

3

モンキーパッチは、それを行うための迅速かつ汚い方法です。他のインポートを行う前に、次の準備を行います。

import foo
import baz
foo.a = baz.m

aこれで、 moduleの属性をその後使用するたびに、必要に応じて、 module の元のクラスではなく、foo実際にmは module のクラスが使用されます。特にきれいではありませんが、潜在的に非常に効果的です。モンキーパッチが他のインポートの前に発生することを確認してください(オブジェクトグラフ全体を追跡して、パッチ適用前に配置されたすべての参照を見つけてに変更することもできますが、それははるかに重くてトリッキーです)。bazafoofoo.abaz.m

于 2009-11-04T16:09:18.620 に答える
1

sed次のスクリプトを試すことができます。

sed -r 's/(^from foo import.*)(xyz, |, xyz)(.*)/\1\3/; T; a\from baz import foobar'

または、同等に:

sed 's/\(^from foo import.*\)\(xyz, \|, xyz\)\(.*\)/\1\3/; T; a\from baz import foobar'

このように試してみると、次の結果が表示されます。

$ echo "from foo import xyz, b, c"|sed -r 's/(^from foo import.*)(xyz, |, xyz)(.*)/\1\3/; T; a\from baz import foobar'
from foo import b, c
from baz import foobar

$ echo "from foo import b, xyz, c"|sed -r 's/(^from foo import.*)(xyz, |, xyz)(.*)/\1\3/; T; a\from baz import foobar'
from foo import b, c
from baz import foobar

$ echo "from foo import b, c, xyz"|sed -r 's/(^from foo import.*)(xyz, |, xyz)(.*)/\1\3/; T; a\from baz import foobar'
from foo import b, c
from baz import foobar

Tコマンド内のコマンドはsed、置換が行われない場合、ラベル (ラベルが指定されていない場合は末尾) に分岐します。この例では、「from baz」行が 1 回だけ追加されます。

$ echo "from foo import d, e, f
from foo import xyz, b, c
from bar import g, h, i"|sed -r 's/(^from foo import.*)(xyz, |, xyz)(.*)/\1\3/;a\from baz import foobar'
from foo import d, e, f
from foo import b, c
from baz import foobar
from bar import g, h, i
于 2009-11-04T20:29:17.753 に答える
1

barがbmrに変更されるため、sed s/a/mは悲惨です。

変数名が本当に短い、および/または一意でない、正規表現できない場合、おそらく最も簡単な方法は挿入することです

from baz import m as a

その後、ファイル内の他のコードを変更する必要はありません。

sed を使用して変更できます

from foo import a,b,c 

from foo import b,c

けれど

from foo import a,b,c 
from baz import m as a

最後のインポートが勝つため、これも機能します。

于 2009-11-04T16:07:24.753 に答える
0

私はモンキーパッチを使用せず、独自の機能を実装します。

import foo

def xyz():
    return foo.xyz()

def b():
    return foo.b()

def c():
    return foo.c()

これで、変更xyz()して自分のやりたいことを何でも実行できるようになりました。明示的に を呼び出したい場合は、変更foo.xyz()できます。

また、そのコードをモジュールに貼り付ければ、現在使用しているすべてのモジュールをfrom foo importグローバルに置き換えることができます。from my_foo importfoo

于 2009-11-05T15:32:35.667 に答える
0

私はロープを使用していませんが、a を baz に移動してからbaz.aを baz.m に名前変更できませんか?

最小限の編集の場合 - ただし、おそらくスタイルと保守性が悪いため、foo.a で baz.m を呼び出します。

于 2009-11-04T16:08:22.870 に答える