我有这样的文件夹结构:
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将包含您启动的脚本的文件夹添加到PYTHONPATH中,因此如果您运行
python application/app2/some_folder/some_file.py
只有文件夹application/app2/some_folder被添加到路径(而不是执行命令的基本目录)。相反,将文件作为模块运行,并在some_folder目录中添加__init__.py。
python -m application.app2.some_folder.some_file
这将把基本目录添加到python路径,然后可以通过非相对导入访问类。
其他回答
据我所知,直接在要导入的函数的文件夹中添加__init__.py文件即可完成此任务。
如果您只想运行脚本而不是实际导入脚本,则exec命令将执行此操作
exec(open('/full/or/relative/path').read())
尝试Python的相对导入:
from ...app.folder.file import func_name
每个前导点都是从当前目录开始的层次结构中的另一个更高级别。
问题?如果这对你不起作用,那么你可能会被许多gotcha的相对进口产品所蚕食。阅读答案和评论以了解更多详细信息:如何修复“尝试在非包中进行相对导入”,即使使用__init__.py
提示:在每个目录级别都有__init__.py。您可能需要python-m application.app2.some_folder.some_file(去掉.py),它可以从顶层目录运行,也可以在PYTHONPATH中包含该顶层目录。呸!
我正在处理项目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中引入了以编程方式导入模块,使您能够更好地控制模块的导入方式。有关更多信息,请参阅文档。