python - 如何使用__init__.py修复“在非包中尝试相对导入”

我正在尝试遵循PEP 328,具有以下目录结构:

pkg/

__init__.py

components/

core.py

__init__.py

tests/

core_test.py

__init__.py

在core_test.py我有以下import语句

from ..components.core import GameLoopEvents

但是,当我运行时,我收到以下错误:

tests$ python core_test.py

Traceback (most recent call last):

File "core_test.py", line 3, in

from ..components.core import GameLoopEvents

ValueError: Attempted relative import in non-package

在我周围搜索时发现“相对路径甚至无法使用__init__.py”和“从相对路径导入模块”,但它们没有帮助。

这里有什么我想念的吗?

12个解决方案

561 votes

详细阐述Ignacio Vazquez-Abrams的答案:

Python导入机制相对于当前文件的-m工作。 直接执行文件时,它没有通常的名称,而是以__package__作为其名称。 所以相对进口不起作用。

正如Igancio建议的那样,您可以使用-m选项执行它。 如果您的程序包的一部分要作为脚本运行,您还可以使用__package__属性来告诉该文件它应该在程序包层次结构中具有什么名称。

有关详细信息,请参见[http://www.python.org/dev/peps/pep-0366/]。

BrenBarn answered 2018-12-24T02:59:38Z

382 votes

是。 您没有将它用作包。

python -m pkg.tests.core_test

Ignacio Vazquez-Abrams answered 2018-12-24T02:59:04Z

195 votes

如果将当前目录附加到sys.path,则可以直接使用import components.core:

if __name__ == '__main__' and __package__ is None:

from os import sys, path

sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))

ihm answered 2018-12-24T02:59:59Z

165 votes

这取决于您希望如何启动脚本。

如果要以经典方式从命令行启动UnitTest,即:

python tests/core_test.py

然后,因为在这种情况下'components'和'tests'是兄弟文件夹,你可以使用sys.path模块的insert或append方法导入相关模块。就像是:

import sys

from os import path

sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )

from components.core import GameLoopEvents

否则,您可以使用'-m'参数启动脚本(请注意,在这种情况下,我们正在讨论一个包,因此您不能给出'.py'扩展名),即:

python -m pkg.tests.core_test

在这种情况下,您可以像以前一样使用相对导入:

from ..components.core import GameLoopEvents

您最终可以混合使用这两种方法,这样无论调用方式如何,您的脚本都可以正常工作。例如:

if __name__ == '__main__':

if __package__ is None:

import sys

from os import path

sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )

from components.core import GameLoopEvents

else:

from ..components.core import GameLoopEvents

Paolo Rovelli answered 2018-12-24T03:00:41Z

14 votes

在core_test.py中,执行以下操作:

import sys

sys.path.append('../components')

from core import GameLoopEvents

Allan Mwesigwa answered 2018-12-24T03:01:01Z

9 votes

如果您的用例是用于运行测试,并且它是接缝,那么您可以执行以下操作。 而不是像nosetests那样运行测试脚本,而是使用测试框架,例如__main__.然后在命令行上输入

$$ py.test

这将在您的目录中运行测试。 这解决了由@BrenBarn指出的nosetests __main__的问题。 接下来,将一个空的__init__.py文件放入您的测试目录中,这将使测试目录成为您的包的一部分。 那你就能做到

from ..components.core import GameLoopEvents

但是,如果您将测试脚本作为主程序运行,那么事情将再次失败。 所以只需使用测试运行器。 也许这也适用于其他测试跑步者,如nosetests,但我还没有检查过。 希望这可以帮助。

deepak answered 2018-12-24T03:01:31Z

5 votes

我的快速修复是将目录添加到路径:

import sys

sys.path.insert(0, '../components/')

v4gil answered 2018-12-24T03:01:51Z

2 votes

旧线程。 我发现添加了__all__= ['submodule', ...]__init__.py文件然后在目标中使用from import *正常工作。

Laurent answered 2018-12-24T03:02:11Z

0 votes

如果有人正在寻找解决方法,我偶然发现了一个。 这是一个背景。 我想测试一下我在文件中的一种方法。 当我从内部运行它

if __name__ == "__main__":

它总是抱怨相对进口。 我尝试应用上述解决方案,但无法工作,因为有许多嵌套文件,每个都有多个导入。

这就是我做的。 我刚刚创建了一个启动器,一个外部程序,可以导入必要的方法并调用它们。 虽然不是一个好的解决方案,但它确实有效。

HappyWaters answered 2018-12-24T03:02:41Z

0 votes

试试这个

import components

from components import *

Vaishnavi Bala answered 2018-12-24T03:03:01Z

0 votes

您可以使用from pkg.components.core import GameLoopEvents,例如我使用pycharm,下面是我的项目结构图片,我只是从root包导入,然后它的工作原理:

Jayhello answered 2018-12-24T03:03:21Z

0 votes

正如Paolo所说,我们有两种调用方法:

1) python -m tests.core_test

2) python tests/core_test.py

它们之间的一个区别是sys.path [0]字符串。 由于解释将在导入时搜索sys.path,我们可以使用tests/core_test.py:

if __name__ == '__main__':

import sys

from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from components import core

在此之后,我们可以使用其他方法运行core_test.py:

cd tests

python core_test.py

python -m core_test

...

注意,py36只测试过。

zhengcao answered 2018-12-24T03:03:54Z

python中__init__导入失败_python - 如何使用__init__.py修复“在非包中尝试相对导入”...相关推荐

  1. R语言导入数据文件(数据导入、加载、读取)、使用readr包中的read_csv函数导入逗号分割文件CSV(Comma Delimited Text File)

    R语言导入数据文件(数据导入.加载.读取).使用readr包中的read_csv函数导入逗号分割文件CSV(Comma Delimited Text File) 目录

  2. R语言导入数据文件(数据导入、加载、读取)、使用haven包的read_dta函数导入Stata中的dta格式文件

    R语言导入数据文件(数据导入.加载.读取).使用haven包的read_dta函数导入Stata中的dta格式文件 目录

  3. R语言导入数据文件(数据导入、加载、读取)、使用haven包的read_sav函数导入SPSS中的sav格式文件

    R语言导入数据文件(数据导入.加载.读取).使用haven包的read_sav函数导入SPSS中的sav格式文件 目录

  4. python自定义模块导入失败_python导入自定义模块失败怎么解决

    py执行文件和模块同属于同个目录(父级目录),才能直接import模块: 如果不在同一目录,可以在python 环境下使用sys.path.append(path)添加相关的路径,但在退出python ...

  5. python中常见的漏洞_Python常见安全漏洞及修复方法集合!你所不会的这里都有!...

    [51CTO技术沙龙]10月27日,让我们共同探索AI场景化应用实现之道 --> 概述 编写安全的代码很困难,当你学习一门编程语言.一个模块或框架时,你会学习其使用方法.在考虑安全性时,你需要考 ...

  6. python爬虫登录12306失败_Python网络爬虫(selenium模拟登录12306网站)

    一.通过selenium自动登录12306官网 1.1 超级鹰打码平台API,创建chaojiyin.py文件 #!/usr/bin/env python#coding:utf-8 importreq ...

  7. python爬虫抖音招聘_Python爬虫:抖音App视频抓包

    APP抓包 对于 App 来说应用内的通信过程和网页是类似的,都是向后台发送请求,获取数据.在浏览器中我们打开调试工具就可以看到具体的请求内容,在 App 中我们无法直接看到.所以我们就要通过抓包工具 ...

  8. python加载dll失败_python tensorflow导入DLL加载失败

    我安装了最新的 python 3.6.4 x64版本 然后使用pip3为cpu-only安装tensorflow C:\>pip3 install tensorflow 但是当我尝试在pytho ...

  9. python post json 解析失败_python中json对象转换出错解决方法

    今天在使用python中的json转换碰到一个问题: 接收一个post的json字符串: s={"username":"admin","passwor ...

最新文章

  1. Python——阶段总结(一)
  2. 移动广告平台到底哪个好?哪个能赚的米米多?
  3. 【OpenCV学习笔记2】OpenCV 完全安装 新增VS2010+OpenCV2.1,新增VS2010+OpenCV2.3.1
  4. linux/centos/集群安装ntp时间同步,自身实验成功
  5. 你认为是宽渠道好还是窄渠道好?请做具体分析
  6. Spring mvc注解方式使用事务回滚
  7. AWS elastic load balancer里的监听器certificate设置
  8. 配置linux系统ip,Linux系统IP地址配置
  9. activexobject对象不能创建_Oracle数据库用户管理之系统权限和对象权限
  10. 数据解读京东上最受欢迎的面包
  11. 小学生眼里的飞鸽传书
  12. 用paddleocr识别汉字_(暑期实践)PaddleHub一键OCR中文识别
  13. Accerlerated c++ 答案
  14. 【译】Vault 学习资源:1.0, 自动解印, 代理, Kubernetes
  15. 系统分析师学习笔记(八)
  16. 儒略日 Julian Date
  17. Oracle VM VirtualBox 安装增强功能
  18. 计算机系统文件夹图标不见了,为何我的电脑文件夹的图标都没有了
  19. vlan是什么?如何划分vlan?如何实现vlan?使用vlan的优点!
  20. ThinkPhp6+Vue+ElementUI前后端分离在线教程

热门文章

  1. 流利说CFO辞职 公司上市一年多股价跌去一半
  2. 小米大杀器稳了?队友泄露小米MIX4 5G预售页面...
  3. 魅族前副总裁李楠谈“苹果对5G判断”,理解万岁!
  4. 华为Mate 30 Pro再爆猛料:更“大”更高级了
  5. SpaceX公布四月份宇宙飞船爆炸原因:由阀门泄露引发
  6. 三星Galaxy Note 10+真机照公布:居中开孔前摄实锤
  7. 第 1 章 多线程基础介绍
  8. 没有信号无服务器,没有信号不用怕“音离”你身边的便携式基站
  9. 什么是原子操作?Linux下有哪些原子操作API
  10. java datainputstream_Java中DataInputStream的用法