Python导入,路径,目录和模组 [英] Python Imports, Paths, Directories & Modules
问题描述
首先让我说,我在过去一周中进行了广泛的研究,但尚未找到这些问题的实际答案-只是一些模糊的答案,并不能真正解释正在发生的事情.如果仅是因为我错过了我想要的东西,对不起-请指向正确的方向.
Let me start by saying I've done extensive research over the course of the past week and have not yet found actual answers to these questions - just some fuzzy answers that don't really explain what is going on. If that's just cause I missed what I was looking for, I'm sorry - please just point me in the correct direction.
我的目录结构是:
TestProject/
runtest*
testpackage/
__init__.py
testmod.py
testmod2.py
testsubs/
testsubmod.py
一些注意事项:
- 我正在Ubuntu上使用python2.7
- 我正在使用bpython进行测试
- 我正在从特定目录运行bpython以测试导入的行为
- 我正在尝试遵循最佳做法.
- 此软件包尚未安装,位于随机的dev目录中
- 此目录不在pythonpath中
- 我在软件包目录中只有一个 init .py
- 嵌套目录中没有 init .py文件
- init .py文件为空
- testpackage/testmod.py包含TestModClass
- testpackage/testsubs/testsubmod.py包含TestSubModClass
- I'm using python2.7 on Ubuntu
- I'm testing with bpython
- I'm running bpython from specific directories to test the way import behaves
- I'm attempting to follow best practices.
- This package is not installed, it's in a random dev directory
- This directory is not in the pythonpath
- I have a single init.py in the package directory
- There are no init.py files in the nested directories
- The init.py file is empty
- testpackage/testmod.py contains TestModClass
- testpackage/testsubs/testsubmod.py contains TestSubModClass
我观察到的事情
- 当我从TestProject运行bpython/导入testpackage 时有效
- 这不会导入testpackage.testmod
- 我根本无法访问testpackage.testmod
- When I run bpython from TestProject/ import testpackage works
- This does not import testpackage.testmod
- I cannot access testpackage.testmod at all
- 我认为这不是正确的方法,如果用户不想导入该模块怎么办?
- 这样做非常好,这样我就可以用STL或扭曲的名称(例如testpackage.logging)来用重叠的名称命名自己的模块,而不会引起错误(不得不像customerlogging这样命名自己的模块,而不是像这样来命名自己的模块,而不是只是mypackage.logging)
问题:
- Python处理软件包和&的导入时是否有所不同?尝试从当前目录导入时,pythonpath中是否存在模块?
- 为什么不导入testpackage可以让我访问testpackage.testmod?导入os后,便可以访问os.path(等).
- 对于软件包,我应该坚持在基本目录中使用单个 init .py,还是应将其嵌套在后续目录中?
- 如何导入指定软件包名称的模块? IE.从testmod.py,我想导入testpackage.testmod2,而不只是testmod2.
- 从subsubs目录导入子模块的正确方法是什么?
- Does python deal differently with imports on packages & modules that exist in the pythonpath than when you are trying to import from your current directory?
- Why doesn't import testpackage give me access to testpackage.testmod? When I import os, I can then access os.path (etc).
- With a package, should I stick to using a single init.py in the base directory, or should I be nesting them in subsequent directories?
- How can I import a module specifying the package name? I.E. from testmod.py, I would like to import testpackage.testmod2 rather than just testmod2.
- What is the proper way to import submodules from the subsubs directory?
- 我看到的唯一解决方案是将该目录添加到 init .py的pythonpath中,但是我不知道这是否正确.
- The only solution I see is to append that directory to the pythonpath from init.py, but I don't know if that's the correct way.
谢谢.
推荐答案
首先,您将在 Python教程的第6节.
(1)python处理软件包&的导入是否有所不同?尝试从当前目录导入时,pythonpath中是否存在模块?
(1) Does python deal differently with imports on packages & modules that exist in the pythonpath than when you are trying to import from your current directory?
不,不是.实际上,Python在导入模块时总是搜索
sys.path
.仅在sys.path
包含具有空字符串的条目(即当前目录)的情况下,才能找到当前目录中的模块.No, it doesn't. Actually, Python always searches
sys.path
when importing modules. Modules in the current directory are only found sincesys.path
contains an entry with the empty string, meaning the current directory.(2)为什么
import testpackage
不能给我访问testpackage.testmod
的权限?导入os
时,然后可以访问os.path
(等).(2) Why doesn't
import testpackage
give me access totestpackage.testmod
? When I importos
, I can then accessos.path
(etc).为了提高效率,
import testpackage
仅加载testpackage/__init__.py
.如果需要testpackage.testmod
,则必须明确导入它:For efficiency,
import testpackage
only loadstestpackage/__init__.py
. If you needtestpackage.testmod
, you have to explicitely import it:import testpackage # Just imports testpackage, not testpackage.testmod! import testpackage.testmod # Import *both* testpackage and testpackage.testmod!
如果您始终要导出
testmod
,请在__init__.py
中导入它,这就是os
(os/__init__.py
)的作用.这样,如果导入testpackage
,则testpackage.testmod
始终隐式可用.If you always want to export
testmod
, import it within__init__.py
, this is whatos
(os/__init__.py
) does. This way,testpackage.testmod
is always available implicitely if you importtestpackage
.由于Python是跨平台的,实际上,由于某些文件系统不区分大小写,因此实际上没有办法在目录中自动一致地自动加载模块. Python不知道是否将
os/path.py
加载为os.path
或os.Path
等.Since Python is cross-platform, there is actually no way to consistently and automatically load modules in a directory, because some filesystems are case-insensitive (Windows!). Python would not know whether to load
os/path.py
asos.path
oros.Path
, etc.(3)使用软件包,我应该坚持在基本目录中使用单个
__init__.py
还是应该将它们嵌套在后续目录中?(3) With a package, should I stick to using a single
__init__.py
in the base directory, or should I be nesting them in subsequent directories?每个子软件包始终需要一个
__init__.py
.关于删除此要求的讨论,但决定保留原样.You always need an
__init__.py
for each subpackage. There were discussions on dropping this requirement, but it was decided to keep it as it is.(4)如何导入指定软件包名称的模块? IE.从
testmod.py
,我想导入testpackage.testmod2
,而不只是testmod2
.(4) How can I import a module specifying the package name? I.E. from
testmod.py
, I would like to importtestpackage.testmod2
rather than justtestmod2
.这应该有效.只要确保您从顶级目录中运行代码即可.如果当前目录为
testpackage
,则testmod
不知道它在软件包中.This should work. Just ensure that you run the code from the top-level directory. If the current directory is
testpackage
,testmod
does not know that it's in a package.首选方法是使用相对的包内导入,但是:
The preferred way is to use relative intra-package imports, though:
from . import testmod2
如果存在名为
testmod2
的全局模块,这可以防止名称冲突,并使您可以毫无问题地使用程序包中的知名模块的名称.This prevents name clashes if there is a global module named
testmod2
and enables you to use the names of well-known modules within your package without problems.(5)从subsubs目录导入子模块的正确方法是什么? 我看到的唯一解决方案是将该目录附加到
__init__.py
的pythonpath中,但是我不知道这是否是正确的方法.(5) What is the proper way to import submodules from the subsubs directory? The only solution I see is to append that directory to the pythonpath from
__init__.py
, but I don't know if that's the correct way.不,不要那样做!绝对不要在其中一个父目录已经位于
sys.path
中时将目录放置到sys.path
中!这可能会导致您的模块被加载两次,这是一件坏事!No, don't do that! Never, ever put a directory to
sys.path
when one of it's parent directories already is insys.path
! This could cause your modules to be loaded twice, which is a bad thing!通常,您应该能够使用绝对或相对导入方式从子包中加载模块:
Usually you should be able to load modules from subpackages using absolute or relative imports:
import testpackage.testsubs.testsubmod from testpackage.testsubs import testsubmod from .testsubs import testsubmod
只需确保在
testsubs/
内创建一个__init__.py
!Just make sure to create a
__init__.py
withintestsubs/
!这篇关于Python导入,路径,目录和模组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!