import package" 的目的是什么?

6 投票
2 回答
913 浏览
提问于 2025-04-15 21:32

我刚刚发现,使用 import package 并不会让这个包里的模块通过 package.module 的方式直接使用。对于 from package import subpackagefrom package import * 也是一样的道理。

那如果我不能访问包里的子模块,只能使用 __init__.py 里定义的内容,导入这个包的意义是什么呢?

我觉得 from package import * 会让命名空间变得很拥挤,这个我能理解,但其他两种方式似乎并不应该有这个问题!我也明白加载所有子模块可能会很耗时间。但我不太明白之前提到的那些“不想要的副作用”,也就是“只有在明确导入子模块时才会发生”的那些问题是什么。

对我来说,如果我不想使用 __init__.py 里提供的内容,使用 import package[.subpackage](或者 from package import subpackage)根本没有意义。

这些不想要的副作用真的那么严重,以至于语言要保护程序员不去引发它们吗?其实,我一直以为 Python 更倾向于“如果程序员想这么做,就让他去做”。

在我的情况下,我确实想通过一句 from package import subpackage 导入所有子模块,因为我需要它们全部!在 __init__.py 文件里告诉 Python 我具体指的是哪些子模块(全部!)对我来说实在是太麻烦了。

请给我一些启发。:)

2 个回答

1

如前所述,解决办法是导入每个子模块。你可以用一种小技巧来避免列出它们:

__init__.py

import os

def import_sub():
  for fn in os.listdir(os.path.dirname(__file__)):
    if fn.endswith(".py") and fn != "__init__.py":
      __import__(".".join([__name__, os.path.basename(fn)[:-3]]), level=0)
import_sub()
del import_sub  # if desired

不过,这种方法在某些情况下可能会出问题。不过,它可以处理常见的情况,暂时使用是可以的。

4

一个包是否在它的 __init__.py 文件中自动导入子模块,这个决定是由包的创建者来定的。比如说,os 这个包就会自动导入 os.path,所以你可以直接使用:

import os
print os.path.abspath('somefile')

包的创建者可以根据实际情况来决定什么做法最好。如果自动加载所有子模块需要花费很长时间,而且这些子模块用到的机会不多,那可能就不应该这样做。如果所有的子模块都是必须的,那就应该自动导入它们。

如果你觉得某个包导入的模块不够用,你可以自己写一个“包装模块”,把需要的模块都导入进去,然后用 from wrappermodule import * 来使用它。

撰写回答