我有这样的文件夹结构:

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正在Python目录中查找此文件,但没有找到它。您必须指定您所指的是您所在的目录,而不是Python目录。

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

从application.app.folder.file导入func_name

为此:

from .application.app.folder.file import func_name

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

其他回答

所以我刚刚右键单击了我的IDE,并添加了一个新文件夹,我想知道为什么不能从中导入。后来我意识到我必须右键单击并创建一个Python包,而不是一个经典的文件系统文件夹。或者一种事后分析方法,添加__init__.py(这使得python将文件系统文件夹视为一个包),如其他答案中所述。在这里添加这个答案,以防有人走这条路。

我正在处理项目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版本安全的方式导入由路径给定的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())

重要警告:该模块将被视为顶级模块;从父包中的任何相对导入都将失败。

你可以使用pip的pipinstall-e。命令您必须在项目目录的根目录中创建一个名为setup.py的文件,该文件包含以下内容:

from setuptools import find_packages, setup

setup(
    name='src',
    packages=find_packages(),
    version='0.1.0',
    description='my_project',
    author='author',
    license='MIT',
)

然后,输入pipinstall-e。而在项目的根目录中。这将使所有目录都能以其名称作为模块进行调用。例如,如果根目录包含子目录module1和module2,每个子目录中都有脚本,则可以使用以下命令从任何子目录访问module1:

将模块1.script1导入为script1

没有问题:

from application.app.folder.file import func_name

只需确保文件夹还包含__init__.py,这允许它作为包包含。不知道为什么其他答案都提到了巨蟒。