我是在不小心把python2.7的site-packages给加到$PYTHONPATH中污染了builtin的模块查找顺序,使得在激活python3.9.1、python3.9.5的虚拟环境时、初始化时在python3的re.py模块导入enum.IntFlag报“enum模块没有IntFlag属性错”,见下。解决办法是1、将python2的enum模块卸载掉,从而python3.9环境查找enum模块时可以查找到python3的,python2用到enum的时候建立一个python2的虚拟环境使用;2、将python2包含enum模块的site-packages从$PYTHONPATH中移除;
参考:https://blog.csdn.net/qq_41185868/article/details/80599336
我的问题现象:
尚未添加python2包含enum模块的site-packages路径到$PYTHONPATH之前,python3.9.5环境激活正常,导入enum模块是查找到的python3.9的版本,包含有IntFlag字段:
haypin@HaypinsMBP ~ source ~/.zshrc
haypin@HaypinsMBP ~ echo $PYTHONPATH
/Users/haypin/.local/ros/kinetic/lib/python2.7/dist-packages:/Users/haypin/catkin_ws/devel/lib/python2.7/dist-packages
haypin@HaypinsMBP ~ python --version
Python 3.9.1
haypin@HaypinsMBP ~ python
Python 3.9.1 (default, Dec 11 2020, 06:28:49)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import enum
>>> enum.__file__
'/Users/haypin/miniconda3/lib/python3.9/enum.py'
>>> enum.IntFlag
<enum 'IntFlag'>
>>> exit()
haypin@HaypinsMBP ~ conda activate Py3.9.5
(Py3.9.5) haypin@HaypinsMBP ~
误将python2包含enum模块的site-packages路径/Users/haypin/.local/lib/python2.7/dist-packages添加到$PYTHONPATH之后,python3.9.5环境激活报enum.IntFlag属性没有,python3.9.1导入enum模块是首先查找到的/Users/haypin/.local/lib/python2.7/dist-packages的版本,的确没有IntFlag字段:
haypin@HaypinsMBP ~ echo $PYTHONPATH
/Users/haypin/.local/ros/kinetic/lib/python2.7/dist-packages:/Users/haypin/catkin_ws/devel/lib/python2.7/dist-packages:/Users/haypin/.local/lib/python2.7/dist-packages
haypin@HaypinsMBP ~ python --version
Python 3.9.1
haypin@HaypinsMBP ~ python
Python 3.9.1 (default, Dec 11 2020, 06:28:49)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import enum
>>> enum.__file__
'/Users/haypin/.local/lib/python2.7/dist-packages/enum/__init__.py'
>>> enum.IntFlag
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'enum' has no attribute 'IntFlag'
>>> exit()
haypin@HaypinsMBP ~ conda activate Py3.9.5
Traceback (most recent call last):
File "/Users/haypin/miniconda3/bin/conda", line 12, in <module>
from conda.cli import main
File "/Users/haypin/miniconda3/lib/python3.9/site-packages/conda/__init__.py", line 11, in <module>
from json import JSONEncoder
File "/Users/haypin/miniconda3/lib/python3.9/json/__init__.py", line 106, in <module>
from .decoder import JSONDecoder, JSONDecodeError
File "/Users/haypin/miniconda3/lib/python3.9/json/decoder.py", line 3, in <module>
import re
File "/Users/haypin/miniconda3/lib/python3.9/re.py", line 145, in <module>
class RegexFlag(enum.IntFlag):
AttributeError: module 'enum' has no attribute 'IntFlag'
✘ haypin@HaypinsMBP ~
列出python2的包,的确如https://blog.csdn.net/qq_41185868/article/details/80599336所说是enum34模块的锅:
haypin@HaypinsMBP ~ python2 -m pip list | grep enum
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
enum34 1.1.2
Catalina10.15.7系统自带的python2.7内建安装有enum34包,不敢卸载掉这个:
haypin@HaypinsMBP ~ python2
WARNING: Python 2.7 is not recommended.
This version is included in macOS for compatibility with legacy software.
Future versions of macOS will not include Python 2.7.
Instead, it is recommended that you transition to using 'python3' from within Terminal.
Python 2.7.16 (default, Mar 25 2021, 03:11:28)
[GCC 4.2.1 Compatible Apple LLVM 11.0.3 (clang-1103.0.29.20) (-macos10.15-objc- on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import enum
>>> enum.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/enum/__init__.pyc'
>>> exit()
要卸载的是/Users/haypin/.local/lib/python2.7/dist-packages/enum中的enum34模块,我直接重命名了:
haypin@HaypinsMBP ~/.local/lib/python2.7/dist-packages ls -l | grep enum
-rw-r--r-- 1 root staff 29087 1 23 2016 enum34-1.1.2.egg-info
drwxr-xr-x 8 root staff 256 3 27 18:26 enum_0723rename_from_enum
haypin@HaypinsMBP ~/.local/lib/python2.7/dist-packages
此时既使将/Users/haypin/.local/lib/python2.7/dist-packages/添加到$PYTHONPATH,python3.9导入enum模块时也会首先查找到python3.9的enum,问题解决:
haypin@HaypinsMBP ~ echo $PYTHONPATH
/Users/haypin/.local/ros/kinetic/lib/python2.7/dist-packages:/Users/haypin/catkin_ws/devel/lib/python2.7/dist-packages:/Users/haypin/.local/lib/python2.7/dist-packages
haypin@HaypinsMBP ~ python --version
Python 3.9.1
haypin@HaypinsMBP ~ python
Python 3.9.1 (default, Dec 11 2020, 06:28:49)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import enum
>>> enum.__file__
'/Users/haypin/miniconda3/lib/python3.9/enum.py'
>>> exit()
haypin@HaypinsMBP ~ conda activate Py3.9.5
(Py3.9.5) haypin@HaypinsMBP ~ conda deactivate
这本质上是$PYTHONPATH中添加了不同python解释器版本的同名enum模块(python2的enum34,python3的enum)的路径导致按$PYTHONPATH顺序查找并加载到了错误版本的enum模块。