我有这样的文件夹结构:
application
├── app
│ └── folder
│ └── file.py
└── app2
└── some_folder
└── some_file.py
如何从file.py或some_file.py中导入函数?我尝试了:
from application.app.folder.file import func_name
但它不起作用。
我有这样的文件夹结构:
application
├── app
│ └── folder
│ └── file.py
└── app2
└── some_folder
└── some_file.py
如何从file.py或some_file.py中导入函数?我尝试了:
from application.app.folder.file import func_name
但它不起作用。
当前回答
尝试Python的相对导入:
from ...app.folder.file import func_name
每个前导点都是从当前目录开始的层次结构中的另一个更高级别。
问题?如果这对你不起作用,那么你可能会被许多gotcha的相对进口产品所蚕食。阅读答案和评论以了解更多详细信息:如何修复“尝试在非包中进行相对导入”,即使使用__init__.py
提示:在每个目录级别都有__init__.py。您可能需要python-m application.app2.some_folder.some_file(去掉.py),它可以从顶层目录运行,也可以在PYTHONPATH中包含该顶层目录。呸!
其他回答
据我所知,直接在要导入的函数的文件夹中添加__init__.py文件即可完成此任务。
所以我刚刚右键单击了我的IDE,并添加了一个新文件夹,我想知道为什么不能从中导入。后来我意识到我必须右键单击并创建一个Python包,而不是一个经典的文件系统文件夹。或者一种事后分析方法,添加__init__.py(这使得python将文件系统文件夹视为一个包),如其他答案中所述。在这里添加这个答案,以防有人走这条路。
下面的代码以Python版本安全的方式导入由路径给定的Python脚本,无论它位于何处:
def import_module_by_path(path):
name = os.path.splitext(os.path.basename(path))[0]
if sys.version_info[0] == 2:
# Python 2
import imp
return imp.load_source(name, path)
elif sys.version_info[:2] <= (3, 4):
# Python 3, version <= 3.4
from importlib.machinery import SourceFileLoader
return SourceFileLoader(name, path).load_module()
else:
# Python 3, after 3.4
import importlib.util
spec = importlib.util.spec_from_file_location(name, path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
我在psutils.test.__init__.py的第1042行psutils代码库中发现了这一点(最新提交时间为2020年10月9日)。
用法示例:
script = "/home/username/Documents/some_script.py"
some_module = import_module_by_path(script)
print(some_module.foo())
重要警告:该模块将被视为顶级模块;从父包中的任何相对导入都将失败。
我也面临着同样的挑战,尤其是在导入多个文件时,这就是我如何克服的。
import os, sys
from os.path import dirname, join, abspath
sys.path.insert(0, abspath(join(dirname(__file__), '..')))
from root_folder import file_name
只需使用os模块中的change-dir函数:
os.chdir("Here new director")
比正常情况下可以导入的更多信息