python - 从不同文件夹导入文件


我有以下文件夹结构。

application/app/folder/file.py

我想从驻留在另一个Python文件中的file.py导入一些函数

application/app2/some_folder/some_file.py

我试过了

from application.app.folder.file import func_name

和其他一些尝试,但迄今为止我无法正常导入。 我怎样才能做到这一点?



Answers


默认情况下,你不能。 当导入一个文件时,Python只搜索当前目录,运行入口脚本的目录以及包含安装目录的sys.path (实际上它比这个复杂一点,但是这包括在大多数情况下)。

但是,您可以在运行时添加到Python路径中:

# some_file.py
import sys
sys.path.insert(0, '/path/to/application/app/folder')

import file



没有错:

from application.app.folder.file import func_name

只要确保文件夹还包含一个__init__.py ,这允许它被包含在一个包中。 不知道为什么其他答案谈论PYTHONPATH。




当模块位于并行位置时,如问题:

application/app2/some_folder/some_file.py
application/app2/another_folder/another_file.py

这个简写使得一个模块对另一个模块可见:

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



由于你的问题看起来像* nix特定的,我认为一个干净的方法是使用环境变量

PYTHONPATH

如文档中所述: Python2Python3

export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH



据我所知,直接在要导入的函数的文件夹中添加一个__init__.py文件可以完成这项工作。




在linux上为python3工作

import sys  
sys.path.append(pathToFolderContainingScripts)  
from scriptName import functionName #scriptName without .py extension  



考虑将application作为您的python项目的根目录,在applicationappfolderfolder夹中创建一个空的__init__.py文件。 然后在你的some_file.py进行如下修改,以获得func_name的定义:

import sys
sys.path.insert(0, r'/from/root/directory/application')

from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file.
func_name()



这在Windows上适用于我

# some_file.py on mainApp/app2 
import sys
sys.path.insert(0, sys.path[0]+'\\app2')

import some_file



如果从特定路径加载模块的目的是为了在开发自定义模块期间提供帮助,则可以在测试脚本的同一个文件夹中创建一个指向自定义模块根目录的符号链接。 此模块引用将优先于为该文件夹中运行的任何脚本安装的任何其他相同名称的模块。

我在Linux上测试过,但它应该支持符号链接的任何现代操作系统。

这种方法的一个优点是,你可以指向一个模块,坐在你自己的本地SVC分支工作副本,这可以大大简化开发周期时间,减少管理不同版本模块的失败模式。




你的问题是,Python正在寻找这个文件的Python目录,而不是找到它。 你必须指定你正在谈论你所在的目录,而不是Python目录。

要做到这一点你改变这一点:

from application.app.folder.file import func_name

对此:

from .application.app.folder.file import func_name

通过添加点你说的是在这个文件夹中查找应用程序文件夹,而不是在Python目录中查找。

(希望这能解决你的问题!)




我很特别:我使用Python与Python!

我只是完成信息:对于Windows和Linux,相对路径和绝对路径都工作到sys.path (我需要相对路径,因为我在几个PC上和不同的主目录下使用我的脚本)。

而当使用Windows时, \/可以用作文件名的分隔符,当然,您必须将\转换成Python字符串,
一些有效的例子:

sys.path.append('c:\\tools\\mydir')
sys.path.append('..\\mytools')
sys.path.append('c:/tools/mydir')
sys.path.append('../mytools')

(注意:我认为/\更方便,如果它比'Windows原生'更为方便,因为它与Linux兼容并且更容易写入和复制到Windows资源管理器)




将应用程序移至其他环境时,将sys.path.append与绝对路径配合使用并不理想。 使用相对路径并不总是工作,因为当前工作目录取决于脚本如何运行。

由于应用程序文件夹结构是固定的,我们可以使用os.path来获取完整的路径。 例如,如果这是结构:

/home/me/application/app2/some_folder/vanilla.py
/home/me/application/app2/another_folder/mango.py

假设你想导入“芒果”模块。 您可以在vanilla.py中执行以下操作:

import sys, os.path
mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+ '/another_folder/')
sys.path.append(mango_dir)
import mango

当然,你不需要mango_dir变量。

要理解这个工作如何看待这个交互式会话的例子:

>>> import os
>>> mydir = '/home/me/application/app2/some_folder'
>>> newdir = os.path.abspath(os.path.join(mydir, '..'))
>>> newdir
    '/home/me/application/app2'
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder'
>>> 
>>> newdir
'/home/me/application/app2/another_folder'
>>> 

并检查os.path文档。




你可以按f5刷新Python shell,或者进入Run-> Run Module。 这样你就不必改变目录来从文件中读取一些东西。 Python会自动改变目录。 但是如果你想在Python Shell中使用不同目录中的不同文件,那么你可以在sys中更改目录, 就像Cameron之前说的那样。




sys.path.insert(0, '/path/to/application/app/folder')