【问题标题】:Automatic replacement of indirect imports自动替换间接导入
【发布时间】:2022-12-19 23:00:16
【问题描述】:

我有一个定义函数的小模块:

# small_file.py
def func():
...

我有一个更大的模块,可以对该模块进行通配符导入:

# giant_file.py
from small_file import *
...

我有数百个其他文件通过 giant_file 间接导入函数:

# file1.py
from giant_file import func
...

# file2.py
import giant_file.func
...

# file3.py
from giant_file import func, something_not_in_small_file
...

我想自动更改所有这些其他文件以直接从small_file.py 导入。这是为了避免加载所有giant_file.py 的开销。

我的问题是:有什么好方法可以自动将所有这些文件更改为直接导入吗?

我的默认计划是编写一个基于 redbaron 的工具,但我希望可能有一种利用 IDE 重构功能的更轻量级的方法。

【问题讨论】:

  • 只使用您最喜欢的文本搜索和替换工具?
  • @JanWilamowski 天真地完成了,这将在from giant_file import func, something_else 上中断。
  • 那就不要天真地去做。 grep 取出进口商品并进行检查。您可能可以轻松清除其中的大部分。
  • 如果我想对在small_file.py 的数百个其他姐妹文件中定义的数千个其他函数执行相同的操作怎么办?我正在寻找一个自动化的解决方案。
  • 由于 IDE 通常具有基于正则表达式的查找和替换选项,因此自动化它的真正基本方法可能是 something like this。它并没有真正分析导入语句,但您可以避免在 file3.py 等不应该完成的情况下进行替换(通过不匹配逗号)

标签: python refactoring python-import automated-refactoring


【解决方案1】:

我通过编写一个静态分析工具来解决这个问题,该工具分析我的整个代码库并为每个文件构造一个 AST。使用 AST,该工具遍历导入并将读取的每个符号归因于原始分配。然后它使用直接导入重写每个文件中的所有导入(沿途消除未使用的导入)。

该工具遗漏了一些潜在的病态情况,例如动态构造字符串,然后通过 globals() 分配给它们。但它适用于大多数“正常”代码。

我为此使用了redbaron。如果我能再做一次,我会改用LibCST,因为 redbaron 有各种错误和不受支持的 python 语言元素,而 LibCST 似乎更成熟并且得到积极维护。

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 2020-10-13
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-22
    • 1970-01-01
    相关资源
    最近更新 更多