服务公告

服务公告 > 综合新闻 > Python-星耀云

Python-星耀云

发布时间:2026-04-27 18:01
搞过的人都知道,最烦的是Python环境问题:版本混乱、模块找不到、包装不上、编码报错,一套流程下来半天没了,代码还没开始写。本文汇总10年运维里见过最多的Python坑,手把手带你排掉。

一、前言

Python部署环境问题比代码bug还恶心:本地跑得好好的服务器报错,pip装不上,ImportError一堆,版本切换乱套。本文解决:模块导入失败、依赖安装异常、多版本冲突、编码坑这四类高频问题。涉及CentOS/RHEL和Ubuntu不同路径时我会分开标注,别搞混。

二、操作步骤

第1步:确认Python版本和环境

# 先看系统里装了几个Python $ which -a python python2 python3 /usr/bin/python /usr/bin/python2.7 /usr/bin/python3.6 /usr/local/bin/python3.8 # 看具体版本号,2和3语法不兼容,混了要命 $ python --version Python 2.7.18 $ python3 --version Python 3.6.8 # 看pip对应哪个版本,装错地方模块就找不到 $ python -m pip --version pip 21.0.1 from /usr/lib/python2.7/site-packages/pip (python 2.7) $ python3 -m pip --version pip 21.0.1 from /usr/lib/python3.6/site-packages/pip (python 3.6)

预期输出:你会发现很多机器上pip和python版本不对应,比如python3装的模块python命令找不到。

第2步:处理ModuleNotFoundError

# 报错:ModuleNotFoundError: No module named 'requests' # 先确认模块装在哪个Python里 $ python -c "import sys; print(sys.path)" ['', '/usr/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', ...] $ python3 -c "import sys; print(sys.path)" ['', '/usr/lib/python3.6/site-packages', '/usr/local/lib/python3.6/dist-packages', ...] # 用pip3安装,装到python3的site-packages $ python3 -m pip install requests # 安装完后验证 $ python3 -c "import requests; print(requests.__version__)" 2.25.1

预期输出:模块安装位置确认后,记住以后都要用 python3 -m pip 来操作,别裸用pip命令。

第3步:解决pip安装失败问题(网络/权限)

# 报错:pip install 超时或者权限拒绝 # 先试国内镜像,访问速度快 # CentOS/RHEL $ python3 -m pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple # Ubuntu $ sudo python3 -m pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple # 如果报权限错误(Read-only filesystem) # 不要sudo,直接指定用户安装 $ python3 -m pip install --user requests # 验证用户级安装路径 $ python3 -c "import site; print(site.getusersitepackages())" /root/.local/lib/python3.6/site-packages # 把这个路径加到PYTHONPATH $ echo 'export PYTHONPATH=$PYTHONPATH:$(python3 -c "import site; print(site.getusersitepackages())")' >> ~/.bashrc $ source ~/.bashrc

预期输出:国内镜像秒装,用户级安装不依赖系统权限,生产环境推荐用--user。

第4步:创建和管理虚拟环境(venv)

# 项目依赖混乱?用venv隔离 # CentOS/RHEL默认可能没装venv,装一下 $ sudo yum install python3-venv -y # 创建虚拟环境(Ubuntu自带python3-venv) $ python3 -m venv /opt/myproject/env # 激活虚拟环境 $ source /opt/myproject/env/bin/activate # 激活后提示符变了,看这里 (env) [root@localhost ~]# # 现在pip装的东西都在这个env里,跟系统隔离 (env) [root@localhost ~]$ pip list Package Version ---------- ------- pip 21.0.1 setuptools 53.0.0 (env) [root@localhost ~]$ pip install requests flask # 安装成功,现在这个项目的依赖全在env里 # 退出虚拟环境 (env) [root@localhost ~]$ deactivate

预期输出:激活后pip list只有env里的包,系统包不受影响。搞完项目记得写requirements.txt。

第5步:导出和迁移依赖(requirements.txt)

# 在虚拟环境里导出当前依赖 (env) [root@localhost myproject]$ pip freeze > requirements.txt # 查看文件内容 $ cat requirements.txt certifi==2020.12.5 chardet==4.0.0 idna==2.10 requests==2.25.1 urllib3==1.26.4 # 新机器上一键安装 (env) [root@localhost newproject]$ pip install -r requirements.txt # 也可以用pipreqs按实际导入生成,更精准 (env) [root@localhost myproject]$ pip install pipreqs (env) [root@localhost myproject]$ pipreqs . --force # 生成的是项目里真正用到的包,不带传递依赖

预期输出:freeze会包含所有传递依赖,pipreqs只保留你代码import过的,文件更干净。

第6步:解决Python编码问题(UnicodeDecodeError)

# 报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb # 先看系统默认编码 $ python3 -c "import sys; print(sys.getdefaultencoding())" utf-8 # 文件读写时指定编码 with open('test.txt', 'r', encoding='utf-8') as f: content = f.read() # 如果文件是GBK编码的 with open('test.txt', 'r', encoding='gbk') as f: content = f.read() # 爬虫/请求回来的内容,先推断编码 import requests r = requests.get('http://example.com') r.encoding = r.apparent_encoding # 自动推断 print(r.text) # 字符串和字节互转 s = "中文" b = s.encode('utf-8') # str -> bytes print(b) # b'\xe4\xb8\xad\xe6\x96\x87' s2 = b.decode('utf-8') # bytes -> str print(s2) # 中文

预期输出:读文件永远指定encoding='utf-8',网络请求用apparent_encoding推断,别硬写编码名。

第7步:处理Python多版本共存切换(CentOS/RHEL)

# CentOS/RHEL默认python2,系统工具依赖它,别动 # 新项目全用python3,用update-alternatives管理 # 安装多个版本 $ sudo alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1 $ sudo alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.8 2 # 切换默认版本 $ sudo alternatives --set python3 /usr/bin/python3.6 # 或者 $ sudo alternatives --config python3 # 查看当前配置 $ alternatives --display python3 python3 - status is auto. link currently points to /usr/local/bin/python3.8 /usr/bin/python3.6 - priority 1 /usr/local/bin/python3.8 - priority 2 # 切完后验证 $ python3 --version Python 3.8.12

预期输出:update-alternatives是CentOS/RHEL官方多版本管理方式,比改软链接安全,不影响yum/dnf。

第8步:处理Python多版本共存切换(Ubuntu)

# Ubuntu用update-alternatives一样的逻辑 $ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1 $ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 2 $ sudo update-alternatives --config python3 There are 2 choices for the alternative python3 (providing /usr/bin/python3). Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/bin/python3.8 2 auto mode 1 /usr/bin/python3.6 1 manual mode 2 /usr/bin/python3.8 2 manual mode Press <enter> to keep the default choice, or enter selection number: # Ubuntu还有个更直接的方式:pyenv $ curl https://pyenv.run | bash $ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc $ exec $SHELL $ pyenv install 3.9.7 $ pyenv versions system 3.6.8 3.9.7 # 进入目录自动切换版本 $ cd myproject $ pyenv local 3.9.7 $ python --version Python 3.9.7

预期输出:Ubuntu下pyenv更省心,项目级版本隔离,不影响系统Python。

三、常见问题FAQ

Q1:pip install报SSL证书错误,链接被拒绝

老手吐槽:这个问题十有八九是公司内网或者代理搞的鬼,别上来就怪pip。

# 先看完整报错 $ python3 -m pip install requests Collecting requests Could not fetch URL https://pypi.org/simple/requests/: There was a problem confirming the ssl certificate # 方法1:跳过SSL验证(临时用,不推荐生产环境) $ python3 -m pip install requests --trusted-host pypi.org --trusted-host files.pythonhosted.org # 方法2:装公司证书 $ sudo cp company_cert.crt /usr/local/share/ca-certificates/ $ sudo update-ca-certificates # 方法3:设代理 $ export https_proxy=http://proxy.company.com:8080 $ python3 -m pip install requests

Q2:明明装了模块,但import还是报错

老手吐槽:这种情况80%是pip装到了别的Python版本里,先别骂娘,逐层排查。

# 第一步:看装在哪了 $ python3 -c "import sys; print(sys.executable)" /usr/bin/python3 $ python3 -m pip show requests Location: /usr/lib/python3.6/site-packages # 第二步:检查sys.path里有没有这个路径 $ python3 -c "import sys; print('\n'.join(sys.path))" # 第三步:直接看模块文件在不在 # CentOS/RHEL $ ls /usr/lib/python3.6/site-packages/ | grep requests requests-2.25.1.dist-info # Ubuntu $ ls /usr/local/lib/python3.6/dist-packages/ | grep requests # 如果文件存在但还是报错,检查__init__.py有没有损坏 $ python3 -c "import requests; print(requests.__file__)" /usr/lib/python3.6/site-packages/requests/__init__.py # 文件路径有了还是报错,可能PYTHONPATH没包含这个目录 $ export PYTHONPATH=/usr/lib/python3.6/site-packages:$PYTHONPATH

Q3:执行python脚本报错No such file or directory,但文件明明存在

老手吐槽:这坑新人必踩,是shebang行编码问题,别乱怀疑权限。

# 写了个脚本直接跑,报错 $ ./test.py -bash: ./test.py: /usr/bin/python3: bad interpreter: No such file or directory # 但文件确实存在 $ ls -la test.py -rwxr-xr-x 1 root root 42 Jan 15 10:30 test.py # 查看文件实际内容 $ cat -A test.py ^[[32m#!/usr/bin/python3^[[0m^M$ print("hello") # ^M是Windows换行符\r,Linux不认 # 用dos2unix转换,或者sed直接删 $ sed -i 's/\r$//' test.py # 再跑 $ ./test.py hello

Q4:virtualenv和venv用哪个

老手吐槽:Python3.3+自带venv,别再装virtualenv了,除非你要兼容Python2项目。

# Python3直接用venv $ python3 -m venv myenv $ source myenv/bin/activate # 如果要用venv创建Python2环境(真的有必要吗?),装virtualenv $ pip install virtualenv $ virtualenv -p python2.7 py2env # venv创建的环境不带pip,先装 $ python3 -m venv myenv $ source myenv/bin/activate $ curl https://bootstrap.pypa.io/get-pip.py | python

四、总结

核心要点

  • 版本第一:先确认python/python3/pip对应关系,搞混了后面全是坑
  • pip永远用-m调用:python3 -m pip,别裸用pip命令
  • 新项目必用虚拟环境:venv隔离依赖,不然依赖地狱等着你
  • 文件读写指定encoding:utf-8是标准,别让系统猜
  • Windows文件拷过来先查换行符:sed -i 's/\r$//' 是救命命令
  • requirements.txt要进版本库:pip freeze是基础,pipreqs更精准

延伸阅读

记住:Python环境问题都是配置问题,不是代码问题。先把环境搞干净,代码跑不起来再说别的。

上一篇: Docker-星耀云

已经是最后一篇啦!