从不同文件夹导入文件
我有以下文件夹结构。
application/app/folder/file.py
我想从驻留在另一个Python文件中的file.py导入一些函数
application/app2/some_folder/some_file.py
我试过了
from application.app.folder.file import func_name
和其他一些尝试,但迄今为止我无法正常导入。 我该怎么做?
默认情况下,你不能。 当导入一个文件时,Python只search当前目录,运行入口脚本的目录以及包含安装目录的sys.path
(实际上它比这个复杂一点,但是这包括在大多数情况下)。
但是,您可以在运行时添加到Pythonpath中:
# 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。
由于你的问题看起来像* nix特定的,我认为一个干净的方法是使用环境variables
PYTHONPATH
如文档中所述: Python2 , Python3
export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH
当模块位于并行位置时,如问题:
application/app2/some_folder/some_file.py application/app2/another_folder/another_file.py
这个简写使得一个模块对另一个模块可见:
import sys sys.path.append('../')
据我所知,直接在要导入的函数的文件夹中添加一个__init__.py
文件可以完成这个工作。
在linux上为python3工作
import sys sys.path.append(pathToFolderContainingScripts) from scriptName import functionName #scriptName without .py extension
这在Windows上适用于我
# some_file.py on mainApp/app2 import sys sys.path.insert(0, sys.path[0]+'\\app2') import some_file
考虑将application
作为您的python项目的根目录,在application
, app
和folder
夹folder
夹中创build一个空的__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()
如果从特定path加载模块的目的是为了在开发自定义模块的过程中提供帮助,则可以在testing脚本的同一个文件夹中创build一个指向自定义模块根目录的符号链接。 此模块引用将优先于为该文件夹中运行的任何脚本安装的任何其他相同名称的模块。
我在Linux上testing过,但它应该支持符号链接的任何现代操作系统。
这种方法的一个优点是,你可以指向一个坐在你自己的本地SVC分支工作副本的模块,这可以大大简化开发周期时间并减lesspipe理不同版本模块的失败模式。
你的问题是,Python正在寻找这个文件的Python目录,而不是find它。 你必须指定你正在谈论你所在的目录,而不是Python目录。
要做到这一点你改变这一点:
from application.app.folder.file import func_name
对此:
from .application.app.folder.file import func_name
通过添加点你说的是在这个文件夹中查找应用程序文件夹,而不是在Python目录中查找。
(希望这能解决你的问题!)
我很特别:我在Windows上使用Python!
我只是完成信息:对于Windows和Linux,相对path和绝对path都工作到sys.path
(我需要相对path,因为我在几个PC上和不同的主目录下使用我的脚本)。
而当使用Windows时, \
和/
可以用作文件名的分隔符,当然,您必须将\
转换成Pythonstring,
一些有效的例子:
sys.path.append('c:\\tools\\mydir') sys.path.append('..\\mytools') sys.path.append('c:/tools/mydir') sys.path.append('../mytools')
(注意:我认为/
比\
更方便,如果它比'Windows原生'更为方便,因为它与Linux兼容并且更容易写入和复制到Windows资源pipe理器)
你可以按f5刷新Python shell,或者进入Run-> Run Module。 这样你就不必改变目录来从文件中读取一些东西。 Python会自动改变目录。 但是如果你想在Python Shell中使用不同目录中的不同文件,那么你可以在sys中更改目录, 就像Cameron之前说的那样。
将应用程序移至其他环境时,将sys.path.append与绝对path配合使用并不理想。 使用相对path并不总是工作,因为当前工作目录取决于脚本如何运行。
由于应用程序文件夹结构是固定的,我们可以使用os.path来获取完整的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_dirvariables。
要理解这个工作如何看待这个交互式会话的例子:
>>> 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文档。
sys.path.insert(0, '/path/to/application/app/folder')