从父目录导入脚本


77

如何导入驻留在父目录中的模块(python文件)?

这两个目录中都有__init__.py文件,但是我仍然无法从父目录导入文件?

在此文件夹布局中,脚本B尝试导入脚本A:

Folder A:
   __init__.py
   Script A:
   Folder B:
     __init__.py
     Script B(attempting to import Script A)

脚本B中的以下代码不起作用:

import ../scriptA.py # I get a compile error saying the "." is invalid

不完全回答你的问题,但如果你运行初始化的.py文件夹A中,并尝试导入文件夹B或脚本B,脚本A将被成功导入脚本B.内
Michael0x2a

Answers:


76

您无需在Python中导入脚本,而可以导入模块。一些python模块也是可以直接运行的脚本(它们在模块级别上做了一些有用的工作)。

通常,最好使用绝对进口,而不是相对进口。

toplevel_package/
├── __init__.py
├── moduleA.py
└── subpackage
    ├── __init__.py
    └── moduleB.py

moduleB

from toplevel_package import moduleA

如果您想moduleB.py作为脚本运行,请确保的父目录toplevel_package在您的中sys.path


8
在这种情况下,为什么不应该使用系统路径“ hacks”?没有它们,Python很难在这里完成您想做的事情。这里到底有什么缺点?
英国电信

4
@BT « sys.path.append(path_to_parent)»不能解决«“ import ../scriptA.py#我得到一个编译错误,指出”。“无效”»问题。在某些情况下,更改sys.path可能会很有用,例如,如果python本身完成了此操作,或者由3方模块正确处理了所有极端情况,例如import autopath; autopath.add_toplevel_to_syspath()自动添加了toplevel_package的父目录sys.path以允许直接内部模块作为没有任何正确的PYTHONPATH或(virtualenv)安装的任何目录中的脚本(或在REPL中)。
jfs 2012年

3
@JFSebastian是否有某种功能提议,使我们可以明确说明整个项目的主文件夹或软件包是什么,因此我们不必关心将父目录添加到哪个位置,sys.path从而也可以运行子模块主文件或脚本?我有一个项目,我确实需要将导入的脚本作为主要脚本或模块运行,但是我需要做大量的黑客操作,添加路径sys.path以使其在两种情况下均能正常工作。是否可以在virtualenv中工作或使用setuptools以某种方式工作?我真的为此感到挣扎……
nbro

2
@nbro功能称为pip install main-package。您已经可以运行“子模块”(只需使用其绝对名称,例如python -ma.b.c)。如果不清楚;
jfs

8
该解决方案对我不起作用。它引发:“ ImportError:没有名为toplevel_package的模块”
聪明的

34

文档

from .. import scriptA

您可以在程序包中执行此操作,但不能在直接运行的脚本中执行此操作。从上面的链接:

请注意,显式和隐式相对导入均基于当前模块的名称。由于主模块的名称始终为“ __main__”,因此打算用作Python应用程序主模块的模块应始终使用绝对导入。

如果创建导入ABB的脚本,则不会收到ValueError。


28
ValueError:尝试以非打包方式进行相对导入
jgritty,2012年

3
@jgritty,这是因为您正在直接运行的脚本中执行此操作。
罗伯·沃特斯

2
你是对的。如果您调用一个脚本然后导入脚本B
它将起作用。– jgritty 2012年

6
@jgrittysys.path.append("..")是您要寻找的东西

5
终于,六年后,我一直在寻找代码段!
jgritty

5

如果要直接运行脚本,则可以:

  1. 将FolderA的路径添加到环境变量(PYTHONPATH)。
  2. 将路径添加到sys.path脚本中。

然后:

import module_you_wanted
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.