PEP8 – 不在文件顶部导入 sys.path
PEP8 – import not at top of file with sys.path
问题
PEP8 有关于将导入放在文件顶部的规则:
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
但是,在某些情况下,我可能想要执行以下操作:
import sys
sys.path.insert("..", 0)
import my_module
在这种情况下,pep8
命令行实用程序会标记我的代码:
E402 module level import not at top of file
实现 PEP8 符合 sys.path
修改的最佳方法是什么?
为什么
我有这个代码,因为我正在关注 the project structure given in The Hitchhiker's Guide to Python。
该指南建议我有一个 my_module
文件夹,与 tests
文件夹分开,两者都在同一目录中。如果我想从 tests
访问 my_module
,我想我需要将 ..
添加到 sys.path
为了符合 pep8,您应该将您的项目路径包含在 python 路径中,以便执行相对/绝对导入。
为此,您可以看看这个答案:Permanently add a directory to PYTHONPATH
我经常在项目的子目录 foo/tests
中有多个包含测试的文件,而我正在测试的模块在 foo/src
中。为了 运行 来自 foo/tests
的测试没有导入错误,我创建了一个如下所示的文件 foo/tests/pathmagic.py
;
"""Path hack to make tests work."""
import os
import sys
bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)
然后在每个测试文件中,我使用
import pathmagic # noqa
作为第一次导入。 "noqa" 注释阻止 pycodestyle
/pep8
抱怨未使用的导入。
还有另一种解决方法。
import sys
... all your other imports...
sys.path.insert("..", 0)
try:
import my_module
except:
raise
如果只有少量导入,您可以忽略那些 import
行的 PEP8:
import sys
sys.path.insert("..", 0)
import my_module # noqa: E402
我刚刚遇到了一个类似的问题,我想我找到了一个比公认的答案更好的解决方案。
创建一个执行实际 sys.path 操作的 pathmagic
模块,但在 context manager:
内进行更改
"""Path hack to make tests work."""
import os
import sys
class context:
def __enter__(self):
bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)
def __exit__(self, *args):
pass
然后,在你的测试文件中(或任何你需要的地方),你做:
import pathmagic
with pathmagic.context():
import my_module
# ...
这样你就不会收到flake8/pycodestyle的任何抱怨,不需要特别的评论,而且结构看起来也很合理。
为了更加整洁,考虑实际还原 __exit__
块中的路径,尽管这可能会导致惰性导入问题(如果您将模块代码放在上下文之外),所以可能不值得麻烦.
编辑:刚刚在 answer to a different question 中看到一个更简单的技巧:在您的导入项下添加 assert pathmagic
以避免 noqa
注释。
您是否已经尝试过以下方法:
import sys
from importlib import import_module
sys.path.insert("..", 0)
# import module
my_mod = import_module('my_module')
# get method or function from my_mod
my_method = getattr(my_mod , 'my_method')
这个问题已经有几个可行的解决方案,但如果您有许多非初始导入,并且不想用 # noqa: E402
注释每个(或使用另一个提案),以下适用于整个区块:
import sys
sys.path.insert("..", 0)
if True: # noqa: E402
import my_module_1
import my_module_2
...
鉴于要添加的路径是脚本的相对路径,可以使用相对路径解决
from ..mypath import mymodule
from ..mypath.mysubfolder import anothermodule
那就不用再用sys.path.insert()
了。林特停止抱怨。
问题
PEP8 有关于将导入放在文件顶部的规则:
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
但是,在某些情况下,我可能想要执行以下操作:
import sys
sys.path.insert("..", 0)
import my_module
在这种情况下,pep8
命令行实用程序会标记我的代码:
E402 module level import not at top of file
实现 PEP8 符合 sys.path
修改的最佳方法是什么?
为什么
我有这个代码,因为我正在关注 the project structure given in The Hitchhiker's Guide to Python。
该指南建议我有一个 my_module
文件夹,与 tests
文件夹分开,两者都在同一目录中。如果我想从 tests
访问 my_module
,我想我需要将 ..
添加到 sys.path
为了符合 pep8,您应该将您的项目路径包含在 python 路径中,以便执行相对/绝对导入。
为此,您可以看看这个答案:Permanently add a directory to PYTHONPATH
我经常在项目的子目录 foo/tests
中有多个包含测试的文件,而我正在测试的模块在 foo/src
中。为了 运行 来自 foo/tests
的测试没有导入错误,我创建了一个如下所示的文件 foo/tests/pathmagic.py
;
"""Path hack to make tests work."""
import os
import sys
bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)
然后在每个测试文件中,我使用
import pathmagic # noqa
作为第一次导入。 "noqa" 注释阻止 pycodestyle
/pep8
抱怨未使用的导入。
还有另一种解决方法。
import sys
... all your other imports...
sys.path.insert("..", 0)
try:
import my_module
except:
raise
如果只有少量导入,您可以忽略那些 import
行的 PEP8:
import sys
sys.path.insert("..", 0)
import my_module # noqa: E402
我刚刚遇到了一个类似的问题,我想我找到了一个比公认的答案更好的解决方案。
创建一个执行实际 sys.path 操作的 pathmagic
模块,但在 context manager:
"""Path hack to make tests work."""
import os
import sys
class context:
def __enter__(self):
bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)
def __exit__(self, *args):
pass
然后,在你的测试文件中(或任何你需要的地方),你做:
import pathmagic
with pathmagic.context():
import my_module
# ...
这样你就不会收到flake8/pycodestyle的任何抱怨,不需要特别的评论,而且结构看起来也很合理。
为了更加整洁,考虑实际还原 __exit__
块中的路径,尽管这可能会导致惰性导入问题(如果您将模块代码放在上下文之外),所以可能不值得麻烦.
编辑:刚刚在 answer to a different question 中看到一个更简单的技巧:在您的导入项下添加 assert pathmagic
以避免 noqa
注释。
您是否已经尝试过以下方法:
import sys
from importlib import import_module
sys.path.insert("..", 0)
# import module
my_mod = import_module('my_module')
# get method or function from my_mod
my_method = getattr(my_mod , 'my_method')
这个问题已经有几个可行的解决方案,但如果您有许多非初始导入,并且不想用 # noqa: E402
注释每个(或使用另一个提案),以下适用于整个区块:
import sys
sys.path.insert("..", 0)
if True: # noqa: E402
import my_module_1
import my_module_2
...
鉴于要添加的路径是脚本的相对路径,可以使用相对路径解决
from ..mypath import mymodule
from ..mypath.mysubfolder import anothermodule
那就不用再用sys.path.insert()
了。林特停止抱怨。