Python踩坑二三事

603 阅读3分钟

记录进行Python开发的过程中遇到的一些坑以及解决方法。

1. Django项目使用MySQL时报错

当我执行指令python3 manage.py runserver的时候一直报错:

...
/Users/user_name/work/virtualenvs/virtualenv_name/lib/python3.7/site-packages/MySQLdb/_mysql.cpython-37m-darwin.so
  Reason: image not found
...
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?

但是我其实是安装了mysqlclient的,执行pip3 freeze能看到实际上我已经安装了mysqlclient

解决办法:

第一步:安装mysql-connector-c

brew install mysql-connector-c

第二步:建立链接

brew link mysql-connector-c

在建立链接的过程中会有提示,根据提示内容在~/.zshrc文件中添加环境变量:

echo 'export PATH="/usr/local/opt/mysql-client/bin:$PATH"' >> ~/.zshrc

重新执行一下~/.zshrc文件:

source ~/.zshrc

第三步:删除原本安装的mysqlclient

pip3 uninstall mysqlclient==1.4.4 

第四步:不使用缓存地重新安装mysqlclient

pip3 --no-cache-dir install mysqlclient==1.4.4

重新执行python3 manage.py runserver,发现项目能正常运行了。

此方法参考地址,以上的步骤和参考地址中的步骤有所不同。

一个不恰当的解决方法:

这个问题我一开始找到的网上的解决办法是安装pymysql,然后在项目下的应用中的__init__.py文件中添加以下内容:

import pymysql

pymysql.install_as_MySQLdb()

这里已经有一点不恰当的地方,因为我们公司的后端团队的Python项目基本上都是使用的mysqlclient,我相当于是在安装了mysqlclient的基础上又安装了pymysql,有重复。但是因为很快解决了这个报错,所以我接着往下走了。这之后运行项目会有一个报错:

AttributeError: 'str' object has no attribute 'decode'
...
  File "/Users/user_name/work/virtualenvs/virtualenv_name/lib/python3.9/site-packages/django/db/backends/mysql/operations.py", line 146, in last_executed_query
    query = query.decode(errors='replace')

按网上找到的方法,根据报错提示找到django/db/backends/mysql/operations.py文件,把 query = query.decode(errors='replace')修改成query = errors = 'replace'。 这个解决方法在本地很方便修改,也有解决这个报错,问题是当部署到服务器上之后也需要修改服务器上django目录下对应位置的文件,这很不恰当,所以最后还是放弃这种方法,找到了前面提到的解决方法。

2. 端口冲突

有时候可能会存在端口冲突的问题,假如起服务的时候报端口(比如端口8000)冲突,可以使用一个新的端口名起服务:

python manage.py runserver 8080

或者,杀掉占用8000端口的进程:

$ lsof -i :8000
COMMAND  PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
Python  6335 momo   xx   IPv4      xx      0t0  TCP xx

$ kill -9 6335

6335是进程ID(PID)。

3. 使用特定版本的Python

如果电脑里有好几个版本的Python,只想使用某个特定版本的Python,不需要把不用的版本的Python删掉,直接执行以下步骤即可(我遇到的情况是电脑里的是Python3.9,但是我需要Python3.7):

第一步:安装想要的版本的Python

brew install python@3.7

第二步:建立链接

brew link python@3.7

根据提示内容把环境变量添加到~/.zshrc文件中

echo 'export PATH="/usr/local/opt/python@3.7/bin:$PATH"' >> ~/.zshrc

重新执行一下~/.zshrc文件:

source ~/.zshrc

再输入python3检查一下,发现已经变成python3.7.8版本了。

4. python和python3要区分清楚

使用python manage.py runserver运行项目的时候报导入模块出错:

ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?

实际上用了虚拟环境的,Django也安装了的。这是因为我混着使用pippip3pythonpython3导致的,因为我在.zshrc文件中设置了别名:

alias python="/usr/local/opt/python@3.7/bin/python3.7"
alias pip="/usr/local/opt/python@3.7/bin/pip3.7"

在终端上用pip --versionpip3 --version以及python --versionpython3 --version测试过,两者打印的结果是一样的。我默认pythonpython3指令是一样的,但实际上背后肯定有哪里不一样,所以导致了这个问题。

使用python3 manage.py runserver运行项目就不会有以上报错。

5. makemigrations没有检测到变化

有时候修改了Model之后执行python manage.py makemigrations 提示 No changes detected,没有检测到变化。在语句后面加上应用名执行就没有这个问题了:

python manage.py makemigrations app_name

6. ModuleNotFoundError: No module named 'django.core'

报这个错是因为没有找到Django包。我遇到的这个错误的场景不是普遍场景,最终的解决方式不重要,重要的是这个过程。

场景是这样的:我需要修改一个陌生的项目,拉下代码之后,执行了以下步骤:

1.创建并进入一个虚拟环境

mkvirtualenv env_name

2.安装项目依赖

pip3 install -r requirements.txt

3.运行项目

我们的项目一般是这样运行的:

source dev.sh && python3 manage.py runserver

这时候我收到了报错:

ModuleNotFoundError: No module named 'django.core'
...

image.png

pip3 list | grep django查看了下已安装的包,是有Django的。

django-admin --version查看Django的版本也能看到和requiremenets.txt文件中的Django版本一致的版本号。

在终端执行python3,运行python解释器,进入交互模式。输入import django也是没问题的。

我尝试把source dev.sh 去掉,直接执行python3 manage.py runserver果真能执行成功。之后打开dev.sh文件,看到这个文件的最后一行是:python manage.py some_custom_command,这个语句是执行一个自定义指令的,问题就在这里。

在我的这台电脑上pythonpython3是不同的,进入虚拟环境后,只在python3的系统路径中增添了虚拟环境的路径,所以使用python指令找不到在虚拟环境中安装的包,导致报错。

image.png

好在当前python manage.py some_custom_command指令的功能已经改为代码合并时自动处理了,其实不需在这个文件中写,直接注释掉就可以了。

所以解决方案就是注释掉dev.sh文件中的python manage.py some_custom_command这行,并重新执行source dev.sh && python3 manage.py runserver