PEP8有一条关于将导入放在文件顶部的规则:
导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,以及模块全局变量和常量之前。
但是,在某些情况下,我可能想要做类似的事情:
import sys
sys.path.insert("..", 0)
import my_module
在这种情况下,pep8
命令行实用程序会标记我的代码:
E402模块级别导入不在文件顶部
实现PEP8符合sys.path
修改的最佳方式是什么?
我有这段代码,因为我正在关注the project structure中提供的The Hitchhiker's Guide to Python。
该指南建议我有一个my_module
文件夹,与tests
文件夹分开,两者都在同一目录中。如果我想从my_module
访问tests
,我认为我需要将..
添加到sys.path
答案 0 :(得分:51)
如果只有少量导入,您可以忽略这些import
行上的PEP8:
import sys
sys.path.insert("..", 0)
import my_module # noqa: E402
答案 1 :(得分:36)
我的项目的子目录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
抱怨未使用的导入。
答案 2 :(得分:8)
还有另一种解决方法。
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string JSONInput = @"{""SN0124"": {
""category1"": 0,
""output"": {
""ABC"": [],
""DEF"": 0,
""GHI"": ""ABDEF""
},
""category2"": 0,
""category3"": 0
},
""SN0123"": {
""category1"": 0,
""output"": {
""ABC"": [""N1"", ""N2""],
""DEF"": 0,
""GHI"": ""ABDEF""
},
""category2"": 0,
""category3"": 0
}}";
Dictionary<string, Pets> deserializedProduct = JsonConvert.DeserializeObject<Dictionary<string, Pets>>(JSONInput);
Console.ReadKey();
}
}
public class Output
{
public string[] ABC { get; set; }
public int DEF { get; set; }
public string GHI { get; set; }
}
public class Pets
{
public int category1 { get; set; }
public Output output { get; set; }
public int category2 { get; set; }
public int category3 { get; set; }
}
}
答案 3 :(得分:4)
我只是在努力解决类似的问题,我认为我找到了一个比接受的答案更好的解决方案。
创建一个pathmagic
模块,用于执行实际的sys.path操作,但在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__
块中的路径,尽管这可能会导致延迟导入问题(如果将模块代码放在上下文之外),那么可能不值得这么麻烦。 / p>
编辑:只是在answer to a different question中看到了一个更简单的技巧:在导入下添加assert pathmagic
以避免noqa
评论。
答案 4 :(得分:2)
为符合pep8,您应该包含python路径的项目路径,以便执行相对/绝对导入。
为此,您可以查看以下答案:How to Preview Image, get file size, image height and width before upload?
答案 5 :(得分:2)
这个问题已经有几个可行的解决方案,但如果您有多个非初始导入,并且不想用 # noqa: E402
注释每个(或使用其他建议之一) ,以下适用于整个块:
import sys
sys.path.insert("..", 0)
if True: # noqa: E402
import my_module_1
import my_module_2
...
答案 6 :(得分:1)
您是否已经尝试过以下操作:
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')