python的import用法(相对导入,在一个文件夹的python文件导入另外一个文件夹的python文件)

张开发
2026/5/23 5:22:25 15 分钟阅读
python的import用法(相对导入,在一个文件夹的python文件导入另外一个文件夹的python文件)
目录一、相对导入的一般用法二、原理解释三、其他事项四、 全局导入1. 写setup.py文件2. 写包文件3. 把py文件方法整理成包的方法4. 安装最近在写一个foxglove可视化的东西使用python。但是遇到了需要再一个文件夹中的.py文件导入另外一个文件夹中的.py文件的问题一直无法导入成功这里记录一下。我的最初的需求是我想在a.py中导入b.py的内容并执行a.py的文件使用相对导入的办法但是这个实际上是无法做到的他总是给我提示找不到父包。通过查阅资料得到如果当前的文件作为一个执行的文件那么他就是没有父包的那么相对导入的..没有办法被解析就会报错。如果非要这样做不使用相对导入的方式一种解决办法是通过sys.path.append()添加B的路径那么就可以找到B了python导入包默认的搜索空间的环境变量是echo $PYTHONPATH一、相对导入的一般用法在实际的相对导入的场景中一般都是有一个主文件这个是程序执行的入口还有一个包文件夹包文件夹中放着各种各样的功能包一个简单的文件目录结构如下。主文件是main.py功能包的集合文件夹是EE中有AB两个功能包功能包里面有各种功能模块。下面进行测试。# a.py from ..B import b def hello(): b.hello()# b.py def hello(): print(Hello World)# main.py from E.A.a import * hello()之后直接执行main.py输出结果为注意这个E的文件夹是必须得如果没有Emain.py和AB直接在同一目录下他在相对路径转化绝对路径的时候提示已经是最顶层了找不到B。二、原理解释1.直接使用import的路径直接使用import导入包的路径是sys.path环境变量里面的路径。2.带.的相对路径导入方式每个文件都有一个__package__,如果当前py文件是执行程序的入口那么他的__package__是None。对于下面的这个例子如果从start.py作为程序的入口那么moduleA的__package__说就是省略/pkg/subPkg1。如果以moduleA.py为程序的入口那么moduleA的__package__就是None。你想想如果直接以moduleA.py为程序的入口由于__package__是None他就没办法解析.,..这种相对路径啊肯定提示找不到包。如果以start.py为程序入口呢由于__package__ 省略/pkg/subPkg1。那么他对.的解释就是subPkg1 对..的解释就是pkg那麽肯定就能找到模块了。这个故事告诉我们把所有的包方到一个文件夹里面这个文件夹里面可以组织一些子包。把可执行文件放到最外面 采用绝对导入的方法。ok如果非要使用sys.append那么应该如何处理呢比如还是上面截图这个例子。那么在A中直接import moduleB, import moduleX。之后再start.py 中直接sys.append(省略/pkg/subPkg1),sys.append(省略/pkg/subPkg2),三、其他事项对于一些除了包的导入就是文件的路径这种。下面是文件树。我的程序的入口是app.py。但是在instance.py中调用了ctrl.exe。那么由于是在app.py启动的那么他的路径就是默认从app.py开始所以如果想要在instance.py中找到ctrl.exe。那么路径应该写为application/workstation/ctrl.exe。这个和包导入是不同的包导入是从启动文件的路径出发不断地通过相对导入来更改当前的路径而查找文件的相对路径永远是启动文件的路径。四、 全局导入其实相对导入还是很麻烦你需要捋清楚各个包之间的关系什么的。但是全局导入就直接一力降十会。1. 写setup.py文件这个直接在工作空间下建立一个setup.py包名称写成自己工作空间的名称就可以了其他不用管。如果你想这个项目拿给别人用的话可以直接在install_requires下写各个包的版本。之后人家建立一个虚拟环境一个pip install -e .就可以全部配置好了。from setuptools import setup, find_packages setup( namepython_test, # 包名称 version0.1.0, # 版本号 descriptionA sample Python package, # 简短描述 authorjiangcui.jiang, # 作者 author_emailyangzhihuaqq.com, # 作者邮箱 packagesfind_packages(), # 自动查找所有包 include_package_dataTrue, # 如果有非代码资源如数据文件设为 True install_requires[ # 定义依赖项 # requests2.25.1, ], )2. 写包文件新建一个目录coder在这个目录下建立__init__.py,是一个空文件就可以。之后再再这个目录下建立一个fun.py。在这个目录下建立一个tool子目录在这个字目录下建立string_bro, string_sis这两个py文件。文件树如下。之后就可以在main.py中全局导入各个包的文件。import coder.fun as f import coder.tool as tool if __name__ __main__: f.hello() tool.print_bro() tool.print_sis()3. 把py文件方法整理成包的方法一个包里面有很多py文件py文件里面有很多函数或者类。导入这些函数的时候还需要从包到文件再到函数。有一个办法是直接从包到函数。在包的__init__.py里面这样写。from .string_bro import print_bro from .string_sis import print_sis这样这个函数就是包的一部分可以通过包直接找到这些函数。import coder.tool as tool4. 安装各个文件全部写好之后使用pip install -e .就可以全局安装了。这个全局安装由于是pip所以是全局安装到某个环境里面如果切换了环境就不能用了。五、另外一种全局导入1. pyproject.toml下面是pyproject.toml他基本上和setup.py的功能一样但是更加细致。因为setup里面依赖就是依赖pyproject把依赖分为很多种安装的时候可以选择性安装。setup.py传统方式用 Python 代码描述包的元数据/依赖/打包逻辑setuptools.setup(...)灵活但容易写出执行代码的构建逻辑配置分散。pyproject.toml现代标准PEP 518/621用 TOML 配置声明项目元数据、依赖、可选依赖、构建后端等更标准化工具pip、build、poetry、uv 等更容易解析你这个项目用的是setuptools.build_meta说明依然用 setuptools 作为构建后端只是配置放到pyproject.toml里。[build-system] requires [setuptools61.0, wheel] build-backend setuptools.build_meta [project] name agent-autolabel version 0.1.0 description AgentAutolabel - 基于 MCP 架构的自动标注系统 readme README.md license {text MIT} requires-python 3.9 authors [ {name huaibin} ] keywords [mcp, autolabel, llm, agent] classifiers [ Development Status :: 3 - Alpha, Intended Audience :: Developers, License :: OSI Approved :: MIT License, Programming Language :: Python :: 3, Programming Language :: Python :: 3.9, Programming Language :: Python :: 3.10, Programming Language :: Python :: 3.11, Programming Language :: Python :: 3.12, ] dependencies [ fastapi0.128.0, fastmcp2.14.2, sqlmodel0.0.16, redis5.0.1, aiofiles23.2.1, asyncio3.4.3, aiohttp3.13.3, oss22.19.1, urllib32.6.3, tqdm4.67.1, requests2.31.0, sqlalchemy2.0.23, duckdb0.10.0, duckdb-engine0.13.0, datasette0.65.2, datasette-insert0.8, datasette-parquet0.6.1, greenlet3.3.0, aiosqlite0.22.1, pillow12.1.0, openai2.15.0, wget3.2, psutil7.2.2, tenacity9.1.4, ] [project.optional-dependencies] viz [ streamlit1.31.0, streamlit-agraph0.0.45, opencv-python4.8.0, matplotlib3.7.0, open3d0.17.0, scipy1.11.0, ] dev [ pytest7.0.0, pytest-asyncio0.21.0, pytest-cov4.0.0, ] docs [ sphinx7.0.0, sphinx-rtd-theme2.0.0, ] search [ pandas2.3.3, streamlit1.31.0, streamlit-agraph0.0.45, ] all [ fastapi0.128.0, fastmcp2.14.2, sqlmodel0.0.16, redis5.0.1, aiofiles23.2.1, asyncio3.4.3, aiohttp3.13.3, oss22.19.1, urllib32.6.3, tqdm4.67.1, requests2.31.0, sqlalchemy2.0.23, datasette0.65.2, datasette-insert0.8, greenlet3.3.0, aiosqlite0.22.1, pillow12.1.0, openai2.15.0, wget3.2, streamlit1.31.0, streamlit-agraph0.0.45, opencv-python4.8.0, matplotlib3.7.0, open3d0.17.0, scipy1.11.0, psutil7.2.2, pandas2.3.3, datasette-parquet0.6.1, datasette-vega0.6.2, tenacity9.1.4, duckdb0.10.0, duckdb-engine0.13.0, ] [project.scripts] agent-autolabel app:main># 只安装必要依赖 pip install -e . # 安装必要依赖和all pip install -e .[all] # 安装必要依赖和其他的一些 pip install -e .[all,dev]

更多文章