我正在审查代码,我看到了第三方类
# tables.py
from sqlalchemy import Enum
被导入的情况,因为它是本地的
# db_update.py
from .tables import Enum
它有什么缺点吗?似乎是一种允许将来替换
Enum
定义的方法,例如什么时候
sqlalchemy 有一天或另一天被另一个库取代
tables.py
我已经看到这种方法适用于本地包以使导入更短/更清晰,但从未见过第三方库。
I've seen this approach applies for local packages to make imports shorter/clearer but never seen that for third party libraries.
# __init__.py
from .x.y.z import MyClass
从模块中导入特定属性然后像导入模块本身一样对待它会使代码对读者造成混淆,并且会给你的 IDE 的自动完成功能带来问题。
在你的例子中,
db_update.py
中的代码在
tables.py
文件中定义了它自己的
Enum
类时,会起作用,这会掩盖来自
sqlalchemy
的导入。
以下是这种导入方式的一些缺点:
-
可读性差: 查看
db_update.py
的人会认为Enum
是在本地定义的,因为它是从一个本地模块导入的。他们需要追踪导入链才能找到Enum
的真正来源。 -
命名空间问题: 如果
tables.py
在以后的某个时间点添加了自己的Enum
类,则db_update.py
中的代码将会中断,或者在最好的情况下,其行为会有所不同,具体取决于导入的优先级。 -
自动完成功能的混乱: 你的 IDE 无法正确推断出
Enum
的类型,因为它认为它是本地定义的。这将导致代码完成和内省功能的建议减少。 -
难以重构: 如果你决定将
sqlalchemy
替换为另一个库,则需要更新所有导入tables.Enum
的位置,而不是只有一个位置 (tables.py
)。
更好的方法
是直接从
sqlalchemy
导入
Enum
,如下所示:
# db_update.py
from sqlalchemy import Enum
如果你担心将来会替换
sqlalchemy
,你可以创建一个包装器模块,以便在你的代码库中抽象出
sqlalchemy
的使用。但这在大多数情况下都属于过度设计,你最好坚持直接导入,直到你有一个有效的理由不这样做。