也许我没有使用正确的术语,但我正在寻找一段Python代码(在Python中),获取代码的令牌树,进行某种修改,并将其重新组装到蟒。
例如,考虑一下这段代码:
def x(y):
b = 2
if y == b:
foo(y)
我希望能够以编程方式执行此操作:
def x(y):
b = 2
if y == b:
bar(y)
我无法想象没有一个库可以做到这样的事情。提前谢谢。
修改
也许我并不完全清楚。我正在寻找一种工具来读取和操作任意代码,而不是我正在编写的代码。我希望能够即时修改代码。我正在开发的项目是一个测试应用程序:它使用Netflix philosophy尝试以尽可能多的方式随机破坏应用程序的功能,每次都运行测试套件。当测试没有失败时,表明代码覆盖率存在差距和/或代码已经死亡。
答案 0 :(得分:2)
我对此很好奇所以我查看了Apalala发布的链接,这是我想出的:
from token import NAME
from tokenize import generate_tokens, untokenize
from StringIO import StringIO
source = """def x(y):
b = 2
if y == b:
foo(y)"""
result = []
tokens = generate_tokens(StringIO(source).readline)
for toknum, tokval, _, _, _ in tokens:
if toknum == NAME and tokval == "foo":
tokval = "bar"
result.append((toknum, tokval))
print untokenize(result)
结果是:
def x (y ):
b =2
if y ==b :
bar (y )
是的,我知道,间距很难看。我无法弄清楚如何从原始代码维护格式,但就功能而言,这可以满足您的需求。
答案 1 :(得分:1)
在Python中,函数可以像任何其他对象一样传递,因此您应该能够执行以下操作:
def x(fx, y):
b = 2
if y == b:
fx(y)
然后致电:
x(foo, y)
或
x(bar, y)
这是一个精简的测试片段(v 3.1),演示了没有任何bizlogic的概念,只是示例执行和任意数字操作:
def x(fx, y): return fx(y)
def foo(x): return x
def bar(x): return x+1
print(x(foo,1))
print(x(bar,1))
输出:
>>>
1
2
答案 2 :(得分:0)
您可以通过这样的反射来更改您的程序类
class A(object):
def __init__(self, x):
self.x = x
def show(self):
print self.x
def chglobals():
import newmod
reload(newmod)
o = newmod.A(0)
globals()['A'] = o.__class__
def main():
a = A(10)
a.show()
#change and wirte new code
src = inspect.getsource(a.__class__)
src = src.replace("print self.x", 'print "foo" ')
text_file = open("newmod.py", "w")
text_file.write(src)
text_file.close()
chglobals()
#new istances
b = A(20)
b.show()
#convert old istances
a.__class__ = b.__class__
a.show()
main()
答案 3 :(得分:-1)
我将不得不在这里猜测用例,但我会假设在某个时间点你想要将1个功能切换到另一个。使用填充函数的字典可以相对容易地完成此操作。例如:
def foo(x): return x
def bar(b): return x+1
fn = { 'foo': foo, 'bar': bar }
def x(y):
b = 2
func = 'foo'
if y == b:
fn[func](y)
这样您就可以根据字典键选择所需的功能。您只需更改func
的值(例如更改为“bar”)即可。