python-3.x - 如何在 Python 中一致地导入(IDE 检查导入路径与测试运行器不同)
问题描述
Python 导入规则一直让我感到困惑。我希望有人可以简单地解释一下。
我从 David Sale 的“测试 Python”一书中获得了以下 Python3 目录布局。
我在 MacOS Mojave 上运行 Python3.7 并使用 PyCharm 2019.2 。
bank
├── __init__.py
├── bank
│ ├── account.py
│ ├── bank.py
│ └── bank_app.py
├── templates
└── test
├── __init__.py
├── bdd
│ ├── __init__.py
│ ├── features
│ │ ├── __init__.py
│ │ └── bank.feature
│ └── steps *
│ └── steps.py
└── unit
├── __init__.py
├── account_test.py
└── bank_test.py
(* can be ignored as not using lettuce but aloe pkg for python3)
银行/银行/bank.py:
from bank.bank.account import Account
银行/测试/单元/bank_test.py:
from bank.bank.bank import Bank
from bank.bank.account import Account
银行/测试/单位/account_test.py:
from bank.bank.account import Account
bank/test/bdd/features/__init__.py:(用于验收测试,但被单元测试运行者看到)
from bank.bank.bank_app import app
从命令行我可以成功运行单元测试:
鼻子测试--rednose -v
验收测试也通过了:
芦荟--rednose -v
Unresolved Reference ...
但是,除非我删除前导 pkg,否则PyCharm 会报告上述每个导入的模块:
from bank.bank import Bank
from bank.account import Account
但如果我这样做,测试运行者将失败。
如果我删除 __init__.py 文件但 python3 不需要这些文件,跑步者也会失败?
我相信这是因为作为外部工具的跑步者要求路径是绝对的,但 PyCharm 路径是相对于 pkg 的。
问:如何使 PyCharm 和命令行与通用导入路径一起工作?
为了解决这个问题,我尝试(无济于事)将以下内容添加到bank/__init__.py:
import importlib
pkg = importlib.import_module('bank')
# check if it's all there..
def bla(mod):
print(dir(mod))
bla(pkg)
但是,当我从命令行运行它时,我看不到银行模块:
python3 __init__.py
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
编辑 向 PyCharm 添加鼻子测试运行器配置与从命令行运行的鼻子测试运行器具有相同的要求。只有 PyCharm IDE 检查会抱怨导入路径。
编辑
我的项目解释器是系统解释器:/usr/local/bin/python3.7
nosetests 和 aloe 也是系统范围的。
他们使用我的项目导入的其他系统范围的模块(即烧瓶)没有任何问题。
在 PyTest 上找到这篇文章(我没有使用)后对此进行了调查: https ://medium.com/@dirk.avery/pytest-modulenotfounderror-no-module-named-requests-a770e6926ac5
他在其中谈到了系统范围与虚拟环境模块。
18 年 1 月
“如果您在系统范围内安装了 pytest,换句话说,在虚拟环境之外,pytest 有一个讨厌的习惯,即只在您的虚拟环境之外寻找模块!如果您的项目使用的模块仅安装在您的虚拟环境,并且您正在使用系统范围的 pytest,即使您已激活虚拟环境,它也不会找到该模块。”
编辑(可能的解决方案)
将相对导入添加到新文件:
银行/银行/__init__.py
from .account import Account
from .bank import Bank
这使得 PyCharm 检查对单元测试文件感到满意。
将单元测试导入更改为:
银行/测试/单位/account_test.py
from bank import Account
银行/测试/单元/bank_test.py
from bank import Account
from bank import Bank
然后将相对导入添加到:
银行/__init__.py
from .bank.account import Account
from .bank.bank import Bank
并将生产文件导入更改为:
银行/银行/bank.py
from .account import Account
注意我还没有为 bank/test/bdd/features/__init__.py 文件工作,我仍然使用绝对导入,对于芦荟,我不得不将 bank/bank/bank_app.py 上移一级以便查看银行/模板/文件夹。
银行/bank.py
from bank.bank import Bank
解决方案
推荐阅读
- python - 如何从 python dict 生成特定的 JSON?
- java - 无法理解为什么我会收到错误消息“myLexer cannot be cast to org.antlr.runtime.TokenSource”
- php - 是否有基于列值生成数组索引的本机函数?
- sql - 如何使用一个参数过滤单个数据集中的多个值?
- python - 如何从属性文件中读取数据库名称?
- button - SwiftUI - 按钮 - 如何将函数请求传递给父级
- python - 如何仅注释查询集中的几个实例?
- python - 对所有行中不包括空格的总字符求和Python
- scala - 如何自定义 Gatling 的 HTMLReports
- javascript - Turbolinks 和初始化脚本