我有这样的文件夹结构:

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.6上测试的

使用此文件夹结构:

main.py
|
---- myfolder/myfile.py

其中myfile.py包含内容:

def myfunc():
    print('hello')

main.py中的import语句是:

from myfolder.myfile import myfunc
myfunc()

这将打印hello。

其他回答

这里的答案不够清晰,这是在Python 3.6上测试的

使用此文件夹结构:

main.py
|
---- myfolder/myfile.py

其中myfile.py包含内容:

def myfunc():
    print('hello')

main.py中的import语句是:

from myfolder.myfile import myfunc
myfunc()

这将打印hello。

您的问题是Python正在Python目录中查找此文件,但没有找到它。您必须指定您所指的是您所在的目录,而不是Python目录。

要执行此操作,请更改此项:

从application.app.folder.file导入func_name

为此:

from .application.app.folder.file import func_name

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

如果您只想运行脚本而不是实际导入脚本,则exec命令将执行此操作

exec(open('/full/or/relative/path').read())

当模块位于平行位置时,如问题所示:

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

这种速记使一个模块对另一个模块可见:

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

在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中引入了以编程方式导入模块,使您能够更好地控制模块的导入方式。有关更多信息,请参阅文档。