基本上,我有一个很多的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
的所有实例。我可以接受输入in,所以这也没关系:
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这样做吗?或绳索(我没有看到任何明显的东西可以帮助我在这里)?
答案 0 :(得分:3)
猴子修补将是快速而肮脏的方式 - 在进行任何其他导入之前,执行以下初步:
import foo
import baz
foo.a = baz.m
现在,模块a
的属性foo
的每次后续使用实际上将根据需要使用模块m
的类baz
,而不是原始类{{ 1}}模块a
。不是特别干净,但可能非常有效。只需要确保在任何其他导入之前进行猴子修补(您还可以在整个对象图中追逐以找到在修补之前放置到foo
的每个引用,并将其更改为foo.a
,但那方式更重,更棘手)。
答案 1 :(得分:1)
如果变量名称真的很短和/或非唯一,则不可正则, 那么也许最容易做的就是插入
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
也可以,因为上次导入获胜。
答案 2 :(得分: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”行仅附加一次:
$ 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
答案 3 :(得分:0)
我没有使用绳索,但你不能移动到baz然后重命名baz.a到baz.m你可以在其他语言的其他重构工具和rope page建议它可以。
对于最小的编辑 - 但可能更差的风格和可维护性使foo.a调用baz.m
答案 4 :(得分:0)
我不会使用monkeypatching,我会实现自己的功能:
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 import
foo
。