Python 是如何寻找包的路径 import 包和系统冲突 同名 PYTHONPATH
一. 事件
1.1 故障现象:
pycharm 运行 django 项目正常。在服务器上用命令 python3.6 -u /vagrant/dzcxyw/manage.py runserver 192.168.33.66:8000 运行django 报如下错误
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 678, in exec_module File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed File "/vagrant/dzcxyw/extra_apps/ansibleapi/urls.py", line 9, in <module> from ansibleapi.ansible_job import * File "/vagrant/dzcxyw/extra_apps/ansibleapi/ansible_job.py", line 16, in <module> from resource.server_group import ServerGroupPublicAction ModuleNotFoundError: No module named 'resource.server_group'; 'resource' is not a package
1.2 错误分析
从错误提示可知:
在 ansible_job.py 中导入 resource 时候报错:ModuleNotFoundError: No module named 'resource.server_group'; 'resource' is not a package
resource : 是django 项目中一个 app 的名字,怎么说它不是模块呢。
1.3 排查
在 ansible_job.py 中加入如下代码,看看它导入是什么玩意
# -*- coding: utf-8 -*- __author__ = 'wukejia' __time__ = '2018/11/29 13:33' import resource #导入 resource 模块 print("resource location",resource.__file__) # 打印 模块路径 from ambase.myfuns.myresault import ResaultDict as resault ...
运行代码,查看 reousrce location...
[vagrant@dzcxyw vagrant]$ /home/vagrant/.pyenv/versions/3.6.6/bin/python3.6 -u /vagrant/dzcxyw/manage.py runserver 192.168.33.66:8000 Performing system checks... resource location /home/vagrant/.pyenv/versions/3.6.6/lib/python3.6/lib-dynload/resource.cpython-36m-x86_64-linux-gnu.so Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f4acb62a9d8>
我操!! 怎么引入的是 resource.cpython-36m-x86_64-linux-gnu.so 这个玩意 !!!!
查了一下原来 官方也有个模块叫 resource
1.4 解决
a. 把你的 django app resource 重命名
b[推荐]. 设置环境变量,把它的路径提前。resource 在 apps 下
export PYTHONPATH=/vagrant_data/extra_apps:/vagrant_data/apps:$PYTHONPATH
有人会说把模块 resource.cpython-36m-x86_64-linux-gnu.so 重命名不就好了,某些第三包/工具可能依赖于它,譬如:ipython
from __future__ import absolute_import 不能解决
1.5 PYTHONPATH
关于pythonpath:[点此查看 python 官网解释 pythonpath]
PYTHONPATH 是 Python 搜索路径,默认我们 import 导入模块都会从 PYTHONPATH 里面寻找。
打印PYTHONPATH:
import os print sys.path
2 本故障总结
我们重新 export PATHTONPATH 目的是把 apps 和 extra_app 放在前面,这样 import 就优先找到这两个 文件夹下的 resource 而不会去找 resource.cpython-36m-x86_64-linux-gnu.so
参考:
resource.cpython-36m-x86_64-linux-gnu.so 是 resource 的模块
resource 模块的官方文档 https : //docs.python.org/3.7/library/resource.html
from __future__ import absolute_import 作用是拒绝隐式引用导入
共 0 条评论