首页 > 解决方案 > 如何阻止 Python 'import' 也导入文件名?

问题描述

我有以下目录结构:

project/
  \__ module/
        \__ __init__.py
        \__ stuff.py


__init__.py文件如下所示:

from . import stuff as othername


但是,当我打开 python 交互式解释器并导入模块module,并调用dir()模块时,我得到以下结果:

>>> dir(module)
['__builtins__',
 '__cached__',
 ...
 'othername',
 'stuff']

如您所见,文件的名称stuff(减去 .py 扩展名)仍然存在。


如果不简单地更改stuff.pyto的名称,othername.py我将如何导入stuffas othername,而不导入stuffas stuff


另外,在旁注中,为同一模块提供别名的最佳方法是什么?

这是应该怎么做的吗...

from . import stuff as othername
aliasname = othername

...还是有另一种被认为是“正确”的方法?


更新

我尝试__all__在我的文件中手动设置__init__.py,但文件本身的名称仍包含在导入中。

__init__.py:

from . import stuff as othername
from . import stuff as aliasname

__all__ = [ 'othername', 'aliasname' ]


我已经设法让以下工作,但我不知道它是否会被视为“良好做法”,或者它是否会提供一致的行为:

__init__.py:

from . import stuff as othername
from . import stuff as aliasname

del stuff

标签: pythonpython-import

解决方案


您无法阻止以真实名称分配模块。毕竟,以下必须设置属性foo bar包模块对象:

# pkg/__init__.py
from .foo import bar

您当然可以del添加后的名称(通过importing 它):

# pkg/__init__.py
from . import foo as bar
del foo

但请注意:它会导致奇怪的情况,例如

>>> import pkg.foo
>>> from pkg.foo import a
>>> pkg.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'pkg' has no attribute 'foo'
>>> import pkg.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'pkg.bar'
>>> pkg.bar.a is a
True
>>> from pkg.bar import a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'pkg.bar'

当然,如果作为一个模块的状态pkg.bar认为是一个实现细节,那么这并不重要,所以没有人会发出import这样的 s。如果您在不隐藏真实名称的情况下添加别名,这也不太重要。(在您的情况下,为什么不调用lex_c89.pyjust c89.py?反正整个包都是词法分析器......)即使那样,这种隐藏也排除了仅导入您需要的模块的性能优势,因为用户无法指示他们需要什么。


推荐阅读