我有这样的文件夹结构:
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 3.4及更高版本中,您可以直接从源文件导入(链接到文档)。这不是最简单的解决方案,但为了完整起见,我将此答案包括在内。
这里有一个例子。首先,要导入的文件名为foo.py:
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!
Python 3.1中引入了以编程方式导入模块,使您能够更好地控制模块的导入方式。有关更多信息,请参阅文档。
其他回答
您可以通过按f5刷新Python shell,或转到运行->运行模块。这样,您就不必更改目录来读取文件中的内容。Python将自动更改目录。但是,如果您想使用PythonShell中不同目录中的不同文件,那么可以在sys中更改目录,正如Cameron之前所说的那样。
创建包的最佳实践是从最高级别目录中的main_module.py等模块运行和访问其他模块。
此结构说明您可以使用顶级目录文件main_module.py来使用和访问子包、父包或同级包和模块。
创建并运行这些文件和文件夹以进行测试:
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'))
现在运行main_module.py
输出为
>>>'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'
打开图片和文件注意事项:
在包结构中,如果您想访问照片,请使用最高级别目录中的绝对目录。
假设您正在运行main_module.py,并且希望在module_1.py中打开photo.png。
module_1.py必须包含的内容是:
对的:
image_path = 'subpackage_1/photo.png'
cv2.imread(image_path)
错误:
image_path = 'photo.png'
cv2.imread(image_path)
尽管module1.py和photo.png位于同一目录。
注:这个答案是针对一个非常具体的问题。对于大多数来自搜索引擎的程序员来说,这不是你想要的答案。通常,您会将文件结构化为包(参见其他答案),而不是修改搜索路径。
默认情况下,您不能。当导入文件时,Python只搜索入口点脚本运行的目录和sys.path,其中包括包安装目录等位置(实际上比这复杂一点,但这涵盖了大多数情况)。
但是,您可以在运行时向Python路径添加:
# some_file.py
import sys
# caution: path[0] is reserved for script path (or '' in REPL)
sys.path.insert(1, '/path/to/application/app/folder')
import file
在我的情况下,我有一个类要导入。我的文件如下:
# /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正在Python目录中查找此文件,但没有找到它。您必须指定您所指的是您所在的目录,而不是Python目录。
要执行此操作,请更改此项:
从application.app.folder.file导入func_name
为此:
from .application.app.folder.file import func_name
通过添加点,您可以在这个文件夹中查找应用程序文件夹,而不是在Python目录中查找。