Python 从不同文件夹导入文件
我有以下文件夹结构Python 从不同文件夹导入文件,python,importerror,python-import,Python,Importerror,Python Import,我有以下文件夹结构 application ├── app │ └── folder │ └── file.py └── app2 └── some_folder └── some_file.py 我想从some_file.py中的file.py导入一些函数 我试过了 从application.app.folder.file导入函数名 还有其他各种尝试,但到目前为止,我无法正确导入。我怎样才能做到这一点?注意:这个答案是针对一个非常具体的问题。对于大多
application
├── app
│ └── folder
│ └── file.py
└── app2
└── some_folder
└── some_file.py
我想从some_file.py
中的file.py
导入一些函数
我试过了
从application.app.folder.file导入函数名
还有其他各种尝试,但到目前为止,我无法正确导入。我怎样才能做到这一点?注意:这个答案是针对一个非常具体的问题。对于大多数来自搜索引擎的程序员来说,这并不是你想要的答案。通常,您会将文件组织成包(请参阅其他答案),而不是修改搜索路径
默认情况下,您不能。导入文件时,Python只搜索入口点脚本运行的目录和包含包安装目录等位置的
sys.path
(实际上比这个要多,但这涵盖了大多数情况)
但是,您可以在运行时向Python路径添加:
# some_file.py
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, '/path/to/application/app/folder')
import file
我认为一种特别的方法是使用文档中描述的: 没有什么错:
from application.app.folder.file import func_name
只需确保
文件夹
还包含一个\uuuu init\uuuu.py
,这样就可以将其作为一个包包含在内。我不知道为什么其他答案会提到PYTHONPATH
据我所知,直接在要导入的函数的文件夹中添加一个\uuuu init\uuuuuu.py
文件就可以了。考虑将应用程序
作为python项目的根目录,在应用程序
、应用程序
和文件夹
中创建一个空的\uuuuuu init\uuuuuuuuuuupy.py
文件。然后在some_file.py
中进行如下更改,以获得func_名称的定义:
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()
如果从特定路径加载模块的目的是在自定义模块的开发过程中提供帮助,则可以在测试脚本的同一文件夹中创建指向自定义模块根的符号链接。对于在该文件夹中运行的任何脚本,此模块引用将优先于以相同名称安装的任何其他模块 我在Linux上进行了测试,但它应该可以在任何支持符号链接的现代操作系统中使用
这种方法的一个优点是,您可以指向位于您自己的本地SVC分支工作副本中的模块,这可以极大地简化开发周期,并减少管理不同版本模块的故障模式。这在windows上对我很有效
# some_file.py on mainApp/app2
import sys
sys.path.insert(0, sys.path[0]+'\\app2')
import some_file
在linux上的python3中为我工作
import sys
sys.path.append(pathToFolderContainingScripts)
from scriptName import functionName #scriptName without .py extension
当模块处于平行位置时,如问题所述:
application/app2/some_folder/some_file.py
application/app2/another_folder/another_file.py
此速记使一个模块对另一个模块可见:
import sys
sys.path.append('../')
您的问题是Python正在Python目录中查找此文件,但没有找到它。您必须指定您谈论的是您所在的目录,而不是Python目录 要执行此操作,请更改以下内容:
从application.app.folder.file导入函数名
为此:
from .application.app.folder.file import func_name
通过添加点,您的意思是在这个文件夹中查找应用程序文件夹,而不是在Python目录中查找。我很特别:我在Windows中使用Python 我只需要完整的信息:对于Windows和Linux,相对路径和绝对路径都适用于
sys.path
(我需要相对路径,因为我在多台电脑上和不同的主目录下使用脚本)
使用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资源管理器)您可以按f5刷新Python shell,或者转到运行->运行模块。这样,您就不必更改目录来读取文件中的内容。Python将自动更改目录。但是,如果您想使用Python Shell中不同目录中的不同文件,那么可以在前面的sys中更改目录 将应用程序移动到其他环境时,使用带有绝对路径的sys.path.append
并不理想。使用相对路径并不总是有效,因为当前工作目录取决于脚本的调用方式
由于应用程序文件夹结构是固定的,因此我们可以使用os.path
获取要导入的模块的完整路径。例如,如果这是结构:
/home/me/application/app2/some_folder/vanilla.py
/home/me/application/app2/another_folder/mango.py
main.py
|
---- myfolder/myfile.py
假设您想要导入芒果模块。您可以在vanilla.py中执行以下操作:
当然,您不需要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'
>>>
并检查文档
还值得注意的是,使用时处理多个文件夹更容易,因为可以使用虚线模块名。在我的例子中,我有一个类要导入。我的文件如下所示:
# /opt/path/to/code/log_helper.py
class LogHelper:
# stuff here
在我的主文件中,我通过以下方式包含了代码:
import sys
sys.path.append("/opt/path/to/code/")
from log_helper import LogHelper
尝试Python的相对导入:
from ...app.folder.file import func_name
每个前导点是层次结构中的另一个更高级别,从当前目录开始
问题?如果这对你不起作用,那么你很可能会被gotcha的相对导入所影响。 有关更多详细信息,请阅读答案和评论:
提示:在每个目录级别都有
\uuuu init\uuuu.py
。您可能需要从顶级目录运行的python-m application.app2.some_文件夹.some_文件
(离开.py),或者在PYTHONPATH中有该顶级目录。呸 这里的答案不够清晰,这是在Python 3.6上测试的
使用此文件夹结构:
/home/me/application/app2/some_folder/vanilla.py
/home/me/application/app2/another_folder/mango.py
main.py
|
---- myfolder/myfile.py
其中myfile.py
包含以下内容:
def myfunc():
print('hello')
main.py
中的导入语句是:
from myfolder.myfile import myfunc
myfunc()
这将打印hello。Fir
import sys
sys.path.insert(0, '/the/folder/path/name-package/')
from name-package import name-module
def announce():
print("Imported!")
import importlib.util
def module_from_file(module_name, file_path):
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
foo = module_from_file("foo", "/path/to/foo.py")
if __name__ == "__main__":
print(foo)
print(dir(foo))
foo.announce()
<module 'foo' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
import importlib.util
def module_from_file(module_name, file_path):
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
baz = module_from_file("bar", "/path/to/foo.py")
if __name__ == "__main__":
print(baz)
print(dir(baz))
baz.announce()
<module 'bar' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
import os, sys
from os.path import dirname, join, abspath
sys.path.insert(0, abspath(join(dirname(__file__), '..')))
from root_folder import file_name
.
├── setup.py
├── MANIFEST.in
└── a
├── __init__.py
├── a.py
└── b
├── __init__.py
└── b.py
from setuptools import setup
setup (
name='a',
version='0.0.1',
packages=['a'],
package_data={
'a': ['b/*'],
},
)
recursive-include b *.*
from __future__ import absolute_import
from a.a import cats
import a.b
cats = 0
from __future__ import absolute_import
from a.b.b import dogs
dogs = 1
python setup.py install
import a
dir(a)
import importlib
scriptName = 'Snake'
script = importlib.import_module('Scripts\\.%s' % scriptName)
script.Hello()
Project
├── main.py
├── .gitignore
|
├── a
| └── file_a.py
|
└── b
└── file_b.py
import sys
try:
# The insertion index should be 1 because index 0 is this file
sys.path.insert(1, '/absolute/path/to/folder/a') # the type of path is string
# because the system path already have the absolute path to folder a
# so it can recognize file_a.py while searching
from file_a import A
except (ModuleNotFoundError, ImportError) as e:
print("{} fileure".format(type(e)))
else:
print("Import succeeded")
try:
from __future__ import absolute_import
# now it can reach class A of file_a.py in folder a
# by relative import
from ..a.file_a import A
except (ModuleNotFoundError, ImportError) as e:
print("{} fileure".format(type(e)))
else:
print("Import succeeded")
import sys
sys.insert(1, /path)
# On top of the module, instead of on the bottom
import os
if __name__ == '__main__':
os.chdir('/path/for/the/regularly/run/directory')
ln -s ~/path/to/original/module/my_module ~/symlink/inside/the/destination/directory/my_module
package/
|
|----- __init__.py (Empty file)
|------- main_module.py (Contains: import subpackage_1.module_1)
|------- module_0.py (Contains: print('module_0 at parent directory, is imported'))
|
|
|------- subpackage_1/
| |
| |----- __init__.py (Empty file)
| |----- module_1.py (Contains: print('importing other modules from module_1...')
| | import module_0
| | import subpackage_2.module_2
| | import subpackage_1.sub_subpackage_3.module_3)
| |----- photo.png
| |
| |
| |----- sub_subpackage_3/
| |
| |----- __init__.py (Empty file)
| |----- module_3.py (Contains: print('module_3 at sub directory, is imported'))
|
|------- subpackage_2/
| |
| |----- __init__.py (Empty file)
| |----- module_2.py (Contains: print('module_2 at same level directory, is imported'))
>>>'importing other modules from module_1...'
'module_0 at parent directory, is imported'
'module_2 at same level directory, is imported'
'module_3 at sub directory, is imported'
image_path = 'subpackage_1/photo.png'
cv2.imread(image_path)
image_path = 'photo.png'
cv2.imread(image_path)
Project
├── main.py
├── .gitignore
|
├── src
├────model
| └── user_model.py
|────controller
└── user_controller.py
from src.model.user_model.py import UserModel
from src.model.user_model.py import UserModel
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
script = "/home/username/Documents/some_script.py"
some_module = import_module_by_path(script)
print(some_module.foo())