此导入工作正常,但在某些方面感觉很脏。主要是它使用切片*中的特定数字来获取父路径,并且它会使flake8 linter烦恼。
import os
import sys
sys.path.append(os.path.dirname(__file__)[:-5])
from codeHelpers import completion_message
它位于文件系统中,看起来有点像这样:
parent_folder
__init__.py
codeHelpers.py
child_folder
this_file.py
(child_folder
实际上称为week1
,因此切片中为5
这个问题与Python import from parent directory极为相似,但在这种情况下,讨论的重点是从终点运行测试是否合适。 In my case,我有一系列目录,其代码使用父级中的帮助程序。
上下文:每个目录都是一组每周练习,所以我希望尽可能简单。
是否有更清洁,更pythonic的方式来进行此导入?
@cco解决了数字问题,但它仍然让烦恼感到不安。
答案 0 :(得分:3)
首先,因为你没有具体说明你得到的lint错误,我将假设这是因为你在sys.path.append
之后有一个导入。
最干净的方法是使用相对或绝对进口。
使用绝对导入:
from parent_path.codeHelpers import completion_message
使用相对导入:
from ..codeHelpers import completion_message
对于原始问题中列出的简单示例,这应该是所有必需的。它很简单,它是pythonic,它是可靠的,它修复了棉绒问题。
您可能会发现上述情况对您不起作用,仍然需要进行sys.path
操作。缺点是您的IDE可能无法从新路径解析对模块的导入,从而导致自动代码完成无效等问题,并将导入标记为错误,即使代码运行正常。
如果您发现仍需要使用sys.path
并希望避免此类情况的lint错误,请创建一个新模块并在其中执行sys.path
操作。然后确保在任何需要修改sys.path
。
例如:
local_imports.py
"""Add a path to sys.path for imports."""
import os
import sys
# Get the current directory
current_path = os.path.dirname(__file__)
# Get the parent directory
parent_path = os.path.dirname(current_path)
# Add the parent directory to sys.path
sys.path.append(parent_path)
然后在目标文件中:
import local_imports # now using modified sys.path
from codeHelpers import completion_message
缺点是它要求您在每个local_imports.py
中包含child_folder
,如果文件夹结构发生变化,则必须修改每个local_imports
文件。
这种模式真正有用的地方是你需要在包中包含外部库(例如在libs
文件夹中)而不需要用户自己安装库。
如果您将此模式用于libs
文件夹,则可能需要确保所包含的库优先于已安装的库。
为此,请更改
sys.path.append(custom_path)
到
sys.path.insert(1, custom_path)
这将使你的自定义路径成为python解释器检查的第二位(第一个仍然是''
,这是本地目录。)
答案 1 :(得分:2)
您可以使用..
从模块中导出级别的模块。在this_file.py中:
from ..codeHelpers import completion_message
如果你想要更多关卡,只需继续添加点......
虽然我在这里,但请注意from ..codeHelpers
是相对导入,并且在导入同一个包中的内容时应始终使用它们。 from codeHelpers
是一个绝对导入,在Python 2中是不明确的(它应该从包中导入还是从您系统上安装的不幸名为codeHelpers
的模块中导入?)实际上禁止在Python 3中作为从同一模块中导入的方式(即它们总是绝对的)。你可以阅读古代PEP 328来解释困难。
答案 2 :(得分:2)
使用绝对导入路径可能更容易,如下所示:
from parent_folder.code_helpers import completion_message
但这需要您确保设置PYTHONPATH环境变量,以便它可以看到最高的根目录(在这种情况下为parent_folder
,我认为)。例如,
PYTHONPATH=. python parent_directory/child_directory/this_file.py
# here the '.' current directory would contain parent_directory
确保同时向child_directory添加__init__.py
。
答案 3 :(得分:1)
您可以通过两次应用os.path.dirname
来删除有关最终目录名称长度的假设。
e.g。而不是os.path.dirname(__file__)[:-5]
,请使用os.path.dirname(os.path.dirname(__file__))
答案 4 :(得分:1)
无论哪种方式,你都要乱搞。如果你的主要目标是避免剥落警告
noqa
评论 exec(open("../codeHelpers.py").read(), globals())
你可以传递一个带解释器选项-c的文件名(不应该打扰flakes8)