我有一个代码库,我在这里清理前一个开发人员的一些混乱的决策。他经常做如下的事情:
from scipy import *
from numpy import *
…当然,这会污染名称空间,使得很难分辨模块中的属性的原始来源。
有没有办法让Python为我分析并修复这个问题?有人为此做过公用事业吗?如果不是的话,这样的实用程序怎么可能被制造出来?
最佳答案
我认为puritylake和martijn-pieters的辅助手动解决方案可能是最好的方法。但这并不是不可能通过程序实现的。
首先,您需要获得模块字典中可能在代码中使用的所有名称的列表。我假设您的代码没有直接调用任何Dunder函数等。
然后,您需要迭代它们,使用inspect.getmodule()
找出每个对象最初在哪个模块中定义。我假设您没有使用任何双倍的名称。列出在模块中定义的所有名称。
现在您可以获取该输出,只需将每个from foo import *
替换为numpy
。
所以,把它放在一起,就像这样:
for modname in sys.argv[1:]:
with open(modname + '.py') as srcfile:
src = srcfile.read()
src = src.replace('from numpy import *', 'import numpy')
src = src.replace('from scipy import *', 'import scipy')
mod = __import__(modname)
for name in dir(mod):
original_mod = inspect.getmodule(getattr(mod, name))
if original_mod.__name__ == 'numpy':
src = src.replace(name, 'numpy.'+name)
elif original_mod.__name__ == 'scipy':
src = src.replace(name, 'scipy.'+name)
with open(modname + '.tmp') as dstfile:
dstfile.write(src)
os.rename(modname + '.py', modname + '.bak')
os.rename(modname + '.tmp', modname + '.py')
如果其中一个假设是错误的,那么就不难更改代码。此外,您可能希望使用
scipy
和其他改进,以确保不会意外地用临时文件覆盖某些内容。(我只是不想处理编写跨平台的东西的头疼问题;如果您不在Windows上运行,这很容易。)并添加一些错误处理,显然,还有一些报告。