我有这样的文件夹结构:

application
├── app
│   └── folder
│       └── file.py
└── app2
    └── some_folder
        └── some_file.py

如何从file.py或some_file.py中导入函数?我尝试了:

from application.app.folder.file import func_name

但它不起作用。


当前回答

只需使用os模块中的change-dir函数:

os.chdir("Here new director")

比正常情况下可以导入的更多信息

其他回答

如果从特定路径加载模块的目的是帮助您开发自定义模块,则可以在测试脚本的同一文件夹中创建指向自定义模块根目录的符号链接。对于在该文件夹中运行的任何脚本,此模块引用将优先于以相同名称安装的任何其他模块。

我在Linux上测试了这个,但它应该可以在任何支持符号链接的现代操作系统中运行。

这种方法的一个优点是,您可以指向位于您自己的本地SVC分支工作副本中的模块,这可以大大简化开发周期,并减少管理不同版本模块的故障模式。

这对我在窗户上有用

# some_file.py on mainApp/app2 
import sys
sys.path.insert(0, sys.path[0]+'\\app2')

import some_file

哇,我没想到会花这么多时间在这上面。以下内容对我有用:

操作系统:Windows 10

Python:v3.10.0

注意:由于我是Python v3.10.0,所以我没有使用__init__.py文件,这对我来说无论如何都不起作用。

application
├── app
│   └── folder
│       └── file.py
└── app2
    └── some_folder
        └── some_file.py

王旭的第一个解决方案对我有效。为了清楚起见,我将其转发了一个绝对的文件参考:

import sys
sys.path.insert(1, 'C:\\Users\\<Your Username>\\application')
import app2.some_folder.some_file

some_file.hello_world()

替代解决方案:然而,这也对我有效:

import sys
sys.path.append( '.' )
import app2.some_folder.some_file

some_file.hello_world()

虽然,我不明白为什么它会起作用。我以为点是对当前目录的引用。但是,当打印出当前文件夹的路径时,当前目录已列在顶部:

for path in sys.path:
    print(path)

希望有人能在评论中澄清为什么这样做有效。尽管如此,我也希望它能帮助一些人。

我正在处理项目a,我希望用户通过pip-install a使用以下文件列表进行安装:

.
├── setup.py
├── MANIFEST.in
└── a
    ├── __init__.py
    ├── a.py
    └── b
        ├── __init__.py
        └── b.py

设置.py

from setuptools import setup

setup (
  name='a',
  version='0.0.1',
  packages=['a'],
  package_data={
    'a': ['b/*'],
  },
)

歧管in

recursive-include b *.*

a/init.py

from __future__ import absolute_import

from a.a import cats
import a.b

a/a.py

cats = 0

a/b/init.py

from __future__ import absolute_import

from a.b.b import dogs

a/b/b.py

dogs = 1

我通过在MANIFEST.in目录下运行以下命令来安装模块:

python setup.py install

然后,在我的文件系统上的一个完全不同的位置上,我可以运行:

import a
dir(a)

这证实了a.ats确实等于0,a.b.dogs确实等于1,正如预期的那样。

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