在包中隐藏模块导入

Mik*_*ike 5 python

我有一个小包,它有一些依赖项,例如 pandas 和 gensim。文件结构是这样的

/package
    __init__.py
    agg_clean.py
Run Code Online (Sandbox Code Playgroud)

__init__.py文件中,我有import agg_clean所以我能够以链接的方式访问这些功能,例如:

import package as pkg
pkg.agg_clean.function()
Run Code Online (Sandbox Code Playgroud)

但是,我在agg_clean.py,(pandas、os 等)中有几个导入语句。当我像上面那样进行链式导入时,我也可以访问 中的导入agg_clean,例如pkg.agg_clean.os.listdir()

如何在包导入中隐藏各种模块的导入?

Voo*_*OFX 6

tl;dr你不能干净利落。或者更准确地说,你不应该担心这样的事情。

namespace collisions在这种情况下没有,因为 os 模块是在 then name 下加载的pkg.agg_clean.os。如果用户想使用您导入的 os 包,让他们这样做没有坏处。最重要的是,没有什么方法可以阻止他们这样做。

这里有一些有趣的事情要记住。取以下可以被另一个python脚本导入的python模块:

# module_im_importing.py
import os as _os

__all__ = ["echo"]

name_not_available = 'some_constant_string'

def echo(object):
    pass
Run Code Online (Sandbox Code Playgroud)

如果您的用户使用 导入裸模块import module_im_importing,则所有定义的变量都可以在名称下用于其环境module_im_importing

>>> import module_im_importing
>>> dir()  # Lookup local namespace
['__builtins__', '__doc__', '__name__', '__package__', 'module_im_importing']
>>> dir(module_im_importing)  # See defined items in your package.
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'echo', 'name_not_available', 'os']
Run Code Online (Sandbox Code Playgroud)

如果他们改为from module_im_importing import * (这是不鼓励的),则行为会有所不同:

>>> from module_im_importing import *
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'echo']
Run Code Online (Sandbox Code Playgroud)

这会导致文件中定义的名称module_im_importing.py被导入到用户的本地命名空间中。因为我们__all__在您的模块中使用了,所以只有在您的模块中定义的项目__all__才会导入到用户本地命名空间中。例如,如果您定义了一个echo与他们可能正在使用的另一个包冲突的函数,这可能会污染他们的命名空间。

这就是为什么在PEP8中显然不赞成通配符导入的原因。从文件:

Wildcard imports (from <module> import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.

无论如何,请不要为这样的事情担心。如果您的模块的用户不遵循 PEP8,这只是一个问题,并且无论如何都应该向他们展示他们的方式的错误。请记住,在 Python 中,We're all consenting adults here.


Dav*_*ers 0

这实际上只是 python 模块工作方式的副作用。导入到模块中的任何内容都将作为该模块中的顶级对象提供。大多数人并不担心它,只是使用规范的导入路径。