python导包问题,这一篇就够了

解决办法:

将项目所在的根目录添加到sys.path中

在入口文件中加入如下代码:

import sys
import os

# 将 项目的根目录添加到sys.path中
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

# 导入包或模块
from db.mysql.my_connect import connect

一、背景

最近在写Python自动化项目,遇到导包问题,明明导入了,运行时仍报 ImportError 。
一个稍微复杂点的 Python 项目,都会有一定的目录结构,就听上去高大上的框架,如下:
PythonProjectDemo
├─bin
│ main.py
│ __init__.py

├─common
│ __init__.py

├─db
│ │ __init__.py
│ │
│ ├─mongo
│ │ mongodb_connect.py
│ │ __init__.py
│ │
│ └─mysql
│ my_connect.py
│ __init__.py

└─view
__init__.py

目录说明:
bin :程序运行入口
common:通用包
db:数据库相关包,下面又包含MySQL和mongo两个包
view:视图包

如果想在bin/main.py中导入db相关的模块,有的同学可能想这样写:
from db.mysql.my_connect import connect
无疑上面导入肯定会报错,因为main.py 和 db下的mysql不在同一个路径下。

二、Python 导入模块工作原理
Python 在导入模块时,会从一下路径进行查询:
1、程序的主目录
2、PTYHONPATH目录(如果已经进行了设置)
3、标准连接库目录
以上三个目录组成了一个list,可通过sys.path来查看
在导包时就会从sys.path中进行搜索,如果搜索不到,则报ImportError

sys.path输出如下

[
    ‘H:\PycharmProjects\untitled4\PythonProjectDemo\bin‘,
    ‘E:\python\python35\python35.zip‘,
    ‘E:\python\python35\DLLs‘,
    ‘E:\python\python35\lib‘,
    ‘E:\python\python35‘,
    ‘E:\python\python35\lib\site-packages‘
]

所以直接通过 from db.mysql.my_connect import connect 是无法导入的

三、解决办法
思路:
1、将需要导入的包或者模块添加到PTYHONPATH目录(不推荐)
2、将需要导入的包或者模块添加到sys.path中
在main.py中添加如下代码
import sys
sys.path.append(r"H:\PycharmProjects\untitled4\PythonProjectDemo")
from db.mysql.my_connect import connect
运行未报错
但是"H:\PycharmProjects\untitled4\PythonProjectDemo"代码写死了,不灵活。在别的机器上可能就无法运行了
我们可借助os模块动态获得项目路径
__file__:运行文件的文件名,main.py

os.path.abspath(path) 获取文件所在的绝对路径,
os.path.abspath(__file__) # H:\PycharmProjects\untitled4\PythonProjectDemo\bin\main.py
os.path.dirname(p) 获取文件所在的目录
os.path.dirname(os.path.abspath(__file__)) # H:\PycharmProjects\untitled4\PythonProjectDemo\bin
os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 获取项目根目录H:\PycharmProjects\untitled4\PythonProjectDemo

四、最终代码

在main.py中的开始添加如下代码

import sys
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from db.mysql.my_connect import connect

更多分享请关注微信公众号

原文地址:https://www.cnblogs.com/yaoqingzhuan/p/10630894.html

时间: 2024-08-27 12:04:49

python导包问题,这一篇就够了的相关文章

python导包语句执行

今天在做项目中遇到一个问题,在first_page中引用login的登录方法,第一次执行登录可以正常登录,登录成功后,再选择返回主菜单,回到上个页面,再选择登录时报错"login_class isnotdefined" 百思不得其解,后来发现是Python的导包机制问题,import语句只有在单独执行这个模块的时候会主动执行,别的类在调用它的方法时不会执行import语句,因此在进入登录后再选择回到首页,没有执行导包语句,所以会报错"login_class is not de

记一次Python导包经历

最近由于需要写一个脚本调用另一个文件里面的一个方法,试了很久都导包失败,特此记录一下 问题背景 1)脚本文件为send_reward.py,要调用public_model_func.py里面的一个类方法 2)public_model_func.py里面导入了项目的其他包,其导包方式为from src.xxx.xxx import xxx,其中src为项目代码的根目录 3)项目处于运行状态,脚本是后续自己写的 解决过程 1)尝试在send_reward.py里面使用from src.xxx.xxx

python 生成器和迭代器有这篇就够了

本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个需求,看列表 [0,1,2,3,4,5,6,7,8,9],要求你把列表里面的每个值加1,你怎么实现呢? 方法一(简单): info = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] b = [] # for index,i in enumerate(info): # print(i+1) # b.append(i+1) # print(b) for index,i in enumerate(in

理解 Python 装饰器看这一篇就够了

讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,让它变得更厚更长,这样一来,它不仅有遮羞功能,还能提供保暖,不过有个问题,这个内裤被我们改造成了长裤后,虽然还有遮羞功能,但本质上它不再是一条真正的内裤了.于是聪明的人们发明长裤,在不影响内裤的前提下,直接把长裤套在了内裤外面,这样内裤还是内裤,有了长裤后宝宝再也不冷了.装饰器就像我们这里说的长裤,在不

python 设置默认的导包路径

在python中 可以通过 sys 模块添加导包时的搜寻路径, sys.path 返回的是所有默认导包路径的列表(搜索次序从下标为零开始,直到寻找到需要导入的包结束) sys.path.insert(下标,包的路径) ,这样就可以将包的路径添加到指定下标(指定次序) 如在django 项目中的settings.py配置文件中,就可以通过下面这种方式,改变导入app时的默认导包路径 # Build paths inside the project like this: os.path.join(B

python相对导包问题

导包分为:绝对路径.相对路径 在测试时发现不能够使用相对路径 查过之后才知道: 运行模块(如:main.py)中导包只能使用绝对路径,不能使用相对路径 官方文档: Note that relative imports are based on the name of the current module. Since the name of the main module is always __main__, modules intended for use as the main modul

Python自定义包引入【新手必学】

前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:sys_song python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的.py文件所在的目录,然后import.这样的做法,对于少数文件是可行的,但如果程序数目很 多,层级很复杂,就很吃力了.如果你刚学python不久,有问题

Python之路【第十七篇】:Django【进阶篇 】

Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetList(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')

Python开发【第二十二篇】:Web框架之Django【进阶】

Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 新随笔 联系 订阅 管理 随笔-124  文章-127  评论-205 Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻