下载了一个 python 项目,目录是这样子的
- XXXProject
- A
- __init__.py
- xxx.py
- yyy.py
- ...
- scripts
- zzz.sh
xxx.py 的内容是
from A.yyy import YY
if __name__ == "__main__":
# .....
yyy.py 的内容是
class YYY():
# .....
zzz.sh 的内容是
python A/xxx.py
然后我就按照 README 所说,在项目根目录下执行 sh scripts/zzz.sh
,结果报错了,错误是
ModuleNotFoundError: No module named 'A'
这是为什么呢?
按大家的说法....这就是这个项目的README本身写错了?
1
mangoDB 2021-11-05 09:00:00 +08:00
from yyy import YY
|
2
Trim21 2021-11-05 09:02:45 +08:00 via Android
把 XXXProject 文件夹加到 python path 环境变量里
|
3
Latin 2021-11-05 09:18:43 +08:00
from __future__ import absolute_import
from __future__ import division from __future__ import print_function import os.path as osp import sys def add_path(path): if path not in sys.path: sys.path.insert(0, path) this_dir = osp.dirname(__file__) lib_path = osp.join(this_dir, '..', 'lib') add_path(lib_path) |
4
ch2 2021-11-05 09:43:11 +08:00
需要加 path
|
5
frostming 2021-11-05 09:48:44 +08:00 2
|
6
misaka19000 2021-11-05 09:51:31 +08:00
要把 XXXProject 这个目录加到 PythonPATH 里面去
export PYTON_PATH=$PYTHON_PATH:/xxx/xxx/XXXProject |
7
sudoy 2021-11-05 09:54:31 +08:00
|
8
Vegetable 2021-11-05 09:57:09 +08:00
@misaka19000 根目录自动添加的吧
|
9
misaka19000 2021-11-05 10:02:35 +08:00
@Vegetable 谁给你自动添加? Python 怎么知道哪个目录是根目录
|
10
Vegetable 2021-11-05 10:18:09 +08:00
@misaka19000 python 的 sys.path 第一位永远是""
|
12
misaka19000 2021-11-05 10:23:14 +08:00
@Vegetable 有的时候是不会在项目的根路径执行程序的
|
13
2i2Re2PLMaDnghL 2021-11-05 11:08:32 +08:00
我觉得更可能你没有安装这个项目,因为 git clone 下来的不会自动安装
如果根目录下有 setup[.]py 的话,应先运行 pip install -e . (你可能会希望做一个 venv ,以免把 A 安装到系统里去) |
14
jaredyam 2021-11-05 11:10:39 +08:00
我的观点,未验证:
1. zzz.sh 的执行路径(在根目录)和执行方式( python A/xxx.py )没有问题 2. 问题是此时 A/xxx.py 被看作为为一个脚本文件直接执行,却使用了 from A.yyy import YY 从它外部的一个包(其实是包括自己的包,但包不包括自己不重要)导入模块 yyy ,按理来说直接 from yyy import YY 就好了,不需要考虑 A ,直接把 yyy 作为同级模块导入即可 3. 但是按照 2 的解决思路,A 的结构就显得很怪异,A 被强行看作一个包(有__init__.py ),但却又包含脚本。一般实践中,xxx.p 应该被拿出来,放在包外面,比如和 scripts/同级,然后在 zzz.sh 中 python xxx.py ,具体放哪看脚本干的事情,但放包里就是有问题 |
15
2i2Re2PLMaDnghL 2021-11-05 11:11:25 +08:00
|
16
2i2Re2PLMaDnghL 2021-11-05 11:15:13 +08:00
|
17
xingheng 2021-11-05 14:33:57 +08:00
|
18
akaHenry 2021-11-05 16:49:34 +08:00
@Latin sys.path.insert() 这种很脏的做法, 就不要再传播了.
Python 是通过 __init__.py 文件来区分 普通文件夹和 package 目录的. 你 XXXProject/ 目录下, 并没有__init__.py 文件, 你的脚本, 并不会认为这是 Python 项目. 很久不写 py 了. 建议你添加个 __init__.py 文件在 XXXProject/ 目录, 再试一下. Python 的项目路径环境, 没什么复杂的. |
19
akaHenry 2021-11-05 16:51:23 +08:00
|
21
zxCoder OP |
22
Latin 2021-11-05 17:07:52 +08:00
|
23
Latin 2021-11-05 17:08:32 +08:00
基本上开源出来的算法模块现在都是这个套路吼
|
24
misaka19000 2021-11-05 17:26:54 +08:00 2
@orzglory 我就教了怎么了,你哪来的优越感?下次怼人之前麻烦先把你写的代码亮出来看看都是些什么东西
|
25
oOoOoOoOoOo 2021-11-05 20:40:41 +08:00 via Android
working_dir 决定一切
|
26
manfredexz 2021-11-05 21:05:24 +08:00
当你搞不清楚谁说的是对的时候,请查阅官方的文档
https://docs.python.org/3/tutorial/modules.html#the-module-search-path 简单来说先查内置 package 再查脚本的当前目录 再查 PYTHONPATH |
27
ila 2021-11-05 21:28:13 +08:00 via Android
|
28
ila 2021-11-05 21:29:25 +08:00 via Android
不要第一步就改环境变量,该设置的都在安装(软件和包)时设置好了
|
29
XIVN1987 2021-11-05 21:48:25 +08:00
PEP 328: all import statements be absolute by default (searching sys.path only) with special syntax (leading dots) for accessing package-relative imports.
“from A.yyy import YY” 显然是个绝对导入,所以 python 肯定是在 sys.path 中的路径中查找 A 。。那程序要想执行只有两种方法: 1 、把 XXXProject 的路径加入 sys.path 2 、把 A 安装到现有的 sys.path 中去,比如 “lib/site-packages” 目录下 |
30
XIVN1987 2021-11-05 22:04:50 +08:00
```
>>> import sys >>> for x in sys.path: print(repr(x).replace(r'\\', '/')) '' 'C:/Python36/python36.zip' 'C:/Python36/DLLs' 'C:/Python36/lib' 'C:/Python36' 'C:/Python36/lib/site-packages' ``` 当前目录确实在 sys.path 中,但当前目录指的是被 python.exe 直接执行的那个 xxx.py 所在的目录,所以 XXXProject/A 的路径在 sys.path 中,但 XXXProject 不在 sys.path 中。 所以题主的“from A.yyy import YY”执行出错,而一楼的“from yyy import YY”执行正常。 |
32
akaHenry 2021-11-08 12:38:20 +08:00
|
33
akaHenry 2021-11-08 12:40:56 +08:00
@Trim21 所以这些人, 真的可爱. 贴个注释给我看.
27 楼, 跟我指出的问题. 是一致的. 这些不懂装懂的, 就不要出来误导别人. 这下面, 一排连 Python package 模块目录和 普通目录都没搞清楚的, 这基本功, 够可以. |
34
akaHenry 2021-11-08 12:46:55 +08:00
|
35
Trim21 2021-11-08 12:48:58 +08:00
@orzglory 没有__init__.py 文件的还有可能是 python namespace package 啊...
|
37
akaHenry 2021-11-08 12:55:49 +08:00
|
38
onlylovehuan 2021-11-08 13:27:35 +08:00
跑的时候命令行先跑到 XXXProject 路径下面,再执行
|
39
O5oz6z3 2021-11-08 14:00:36 +08:00
#5 和#26 楼的文档说完了。项目可能没问题如#13 #29 所说需要全局安装。
#26 docs.python.org/zh-cn/3/tutorial/modules.html#the-module-search-path #12 docs.python.org/zh-cn/3/using/cmdline.html#cmdarg-script #6 docs.python.org/zh-cn/3/using/cmdline.html#envvar-PYTHONPATH #16 docs.python.org/zh-cn/3/using/cmdline.html#cmdoption-m __init__.py 只是规范问题,加不加效果上我猜区别不大…… |