Python 导入自定义包的正确做法是什么?

查看 101|回复 8
作者:ztm0929   
我是编程新手,正在练习爬虫项目,Python 到底如何导入包?
xxx_project
├── README
└── app
    ├── models.py
    ├── main.py
    └── crawler
        └── scraper_1.py
        └── scraper_2.py
        └── scraper_3.py
models 定义了数据库引擎和会话,我想让 scraper 能够与数据库交互,但是
from ..models import func 会得到报错
ImportError: attempted relative import with no known parent package

from app.models import func 又会得到报错
ModuleNotFoundError: No module named 'app'
网上提到的在 app 目录下创建空白 __init__.py 似乎也没有效果,而 GPT 提到的将 app 目录添加到环境变量是最佳做法吗?还是说我这样的目录结构本身就是错的?
mickerwx   
把你原来的导入删掉 然后在 scraper 里面写上 models 的模型名称,这个时候模型名称会报错,你把鼠标放上去,下面就会出现 import.... 点击一下 就可以了 前提你用的是 pycharm
yanghanlin   
试试 python -m app.main 而非 python app/main.py 呢
ztm0929
OP
  
@yanghanlin hhh 忘记说了,同目录下的 main 是可以导入 models 并成功识别的,不过-m 选项确实网上也有提到,我再试试看
ztm0929
OP
  
@mickerwx 只用 VSCode 哈哈哈,不过我也试试这个方法~
NoOneNoBody   
给个我自用的方案,但我没编译过,不知道编译时会否出错
在项目每个有 py 的子目录,都放一个空的,0 字节的 __init__.py ,项目根目录不需要
然后,所有 import 都写为 from 一级子目录.二级子目录.xxx import ...,即使是内层的 py 也是这样写,总之就是从第一级开始写
例如你这个,app 视为项目根目录,scraper_1.py 里面 import scraper_2 ,就要写成 from crawler import scraper_2 ,或者 import crawler.scraper_2 as ...,就是不要理会在哪一级或者是否同级,都要从第一级开始写 namespace
然后,所有入口程序都应该放在项目根目录,你这个就是 app 这个目录。如果你想直接运行 scraper_1.py ,也要在 app 内另写一个 run_scraper_1.py 把 scraper_1 导入来运行
darksword21   
官方文档 package and module
assassing   
你需要在 app/__init__.py 中手动打入文件中的函数,例如:from .models.py import func ,注意文件名前面的点。然后在 scraper_1.py 中就能直接导入了:from app import func
cnt2ex   
python 会把被执行的脚本所在的目录插入到 sys.path 中,所以 import 都是相对于脚本所在位置计算的,所以一般入口脚本都是在项目根目录,其他东西都是相对于项目根目录。
如果你不想把入口脚本放在根目录,就利用 PYTHONPATH ,在里面加上项目根目录。
比如 PYTHONPATH=/whatever/comes/before/xxx_project/app python main.py
这样你的 import 都可以写成
```
from models import something
from crawler.scrapper_1 import something
```
而不管 main.py 在哪个位置
您需要登录后才可以回帖 登录 | 立即注册

返回顶部