如何阻止 Python 'import' 也导入文件名?

How to stop Python 'import' from importing the filename as well?

我的目录结构如下:

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.py 的名称更改为 othername.py,我将如何将 stuff 导入为 othername,而不将 stuff 导入为 stuff


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

这是应该怎么做的...

from . import stuff as othername
aliasname = othername

...或者还有另一种被认为是 "correct" 的方法吗?


更新

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

__init__.py:

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

__all__ = [ 'othername', 'aliasname' ]


我已经设法让以下内容起作用,但我不知道它是否会被考虑 "good practice" 或者它是否会提供一致的行为:

__init__.py:

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

del stuff

您无法阻止模块以其真实名称分配。毕竟下面要在包模块对象上设置属性foobar

# 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 作为一个模块的 status 被认为是一个实现细节,那么没有人会发布 import就像这些。如果您 添加 别名而不隐藏真实姓名,这也不太重要。 (在你的情况下,为什么不调用 lex_c89.py 只是 c89.py?整个包都是一个词法分析器......)即便如此,这种隐藏也排除了仅导入你需要的模块的性能优势,因为用户无法表明他们需要什么。