我有一个代码库,我在这里清理前一个开发人员的一些混乱的决策。他经常做如下的事情:

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上运行,这很容易。)并添加一些错误处理,显然,还有一些报告。

07-24 09:53
查看更多