Python模块导入是否依赖于代码的运行方式?

2024-04-28 16:12:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我不认为任何语言会像python那样让人头痛,因为导入其他源文件这么简单。所以问题是: 我的模块导入是否需要依赖于代码应该如何运行?你知道吗

我有以下目录结构:

./__init__.py
./config.py
./kmer
./kmer/__init__.py
./kmer/__main__.py
./kmer/__pycache__
./kmer/__pycache__/__init__.cpython-36.pyc
./kmer/__pycache__/__main__.cpython-36.pyc
./kmer/__pycache__/bed.cpython-36.pyc
./kmer/__pycache__/config.cpython-36.pyc
./kmer/__pycache__/reference.cpython-36.pyc
./kmer/__pycache__/sets.cpython-36.pyc
./kmer/bed.py
./kmer/config.py
./kmer/reference.py
./kmer/sets.py

我希望从kmer包中的另一个模块导入khmer中的模块。简单?你知道吗

所以我在bed.py的末尾加上这个:

import reference
import config
import sets

现在,如果我从kmer目录运行python bed.py,事情就可以正常工作了。如果我返回一个目录并调用python kmer/bed.py,情况也会很好。似乎python会搜索相对于给定文件的导入模块。你知道吗

同样,从kmer目录以python -m bed的形式运行它可以正常工作,但是返回一个目录并运行python -m kmer.bed会导致模块错误。在这里,python似乎在解释器的当前目录中查找模块,该目录可能位于文件系统中的任何位置,因此相对于它的导入不起作用。你知道吗

这基本上意味着导入应该取决于代码将如何运行,这毫无意义。我希望你能解释一下这是怎么回事。你知道吗

我看了很多参考资料,包括this问题的答案,这些问题虽然非常详细(实际上是我发现的最好的描述之一),但并不能解决我的问题,也没有提供适当的例子。你知道吗

更新:我认为这个问题更关注于相对导入的不同方面,更确切地说,运行代码的不同方法如何影响导入,而不是它被标记为其副本的方法。这就是我首先提到另一个问题的原因。因此,我不认为这应该是一个重复。你知道吗


Tags: 模块代码pyimport目录configinitmain
1条回答
网友
1楼 · 发布于 2024-04-28 16:12:42

在编写包时,必须始终将其视为包。首先,这意味着在包中使用相对导入:在bed.py中写入from . import reference。你知道吗

这也意味着如何访问它的答案总是一样的:将包含kmer的目录放到sys.path(通常通过PYTHONPATH)。即使将包中的某个模块作为脚本运行,这也是正确的,因此它必须是python -m kmer.bed。你知道吗

不幸的是,将包中的模块作为脚本运行是一个坏主意:该模块的文件仍然可以以其正确的名称再次导入(而不是第一次使用的__main__)。唯一健壮的解决方案是编写一个__main__.py并将作为脚本运行,避免重载公共模块名。你知道吗

最后,不要太注意Python将脚本目录放在sys.path上的“特性”。除了不关心名称冲突的玩具问题之外,这是没有用的,因为任何目录在sys.path上有用的脚本都必须是一个模块(除非有使其名称不是标识符之类的技巧)。此外,如果您希望您的库对安装在其他地方的脚本可用,那么它需要以其他方式运行sys.path。你知道吗

相关问题 更多 >