python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python module enum has no attribute IntFlag问题

Python 3.6.报错 “module ‘enum‘ has no attribute ‘IntFlag‘”的真正原因与解决办法

作者:网罗开发

这篇文章主要为大家详细介绍了Python 3.6.报错 “module ‘enum‘ has no attribute ‘IntFlag‘”的真正原因与解决办法,文中的示例代码讲解详细,有需要的可以了解下

摘要

有一天你刚刚装好 Python 3.6.1,信心满满地敲下命令:

python3

结果刚刚打开控制台,终端就给了你一个当头一棒:

AttributeError: module 'enum' has no attribute 'IntFlag'

看起来好像是 Python 内部的 bug,对吧?

其实并不是。这个问题的根本原因非常“隐蔽”——是你项目(或系统路径)中存在一个名为 enum.py 的文件,覆盖了标准库的 enum 模块

下面我们一起来还原这个坑的全过程。

背景与问题重现

首先,这个问题常出现在以下环境中:

macOS 系统;

Python 版本 3.6.1(但也可能在 3.7 甚至 3.8 出现);

安装路径类似 /Library/Frameworks/Python.framework/...

启动解释器或运行任何 Python 文件时,报如下错误:

AttributeError: module 'enum' has no attribute 'IntFlag'

你可能第一反应是:

“明明 Python 3.6 已经支持 IntFlag 啊,这不应该报错啊?”

是的,Python 3.6.1 的 enum 模块确实定义了 IntFlag 类:

# Python 3.6 源码 enum.py 中的一部分
class IntFlag(Flag):
    pass

那为什么解释器还会报 “enum 没有 IntFlag” 呢?别急,下面揭开谜底。

问题原因分析

Python 的导入机制其实非常简单——它会按照 sys.path 的顺序依次搜索模块。

一旦它在某个路径下找到了名为 enum.py 的文件,它就会优先导入那个文件,而不是标准库自带的。

比如,你的项目结构是这样的:

/Users/yourname/project/
├── enum.py
├── main.py

你在 main.py 里执行了:

import enum

Python 实际上导入的是你项目目录下的 enum.py,而不是标准库的 enum 模块。于是,这个自定义的 enum.py 文件里没有 IntFlag 类,解释器自然就抛出了:

AttributeError: module 'enum' has no attribute 'IntFlag'

本质上是:你“遮蔽”了标准库模块。

实战验证:如何复现这个错误

我们自己来做个小实验,看它是怎么被“遮蔽”的:

# enum.py (放在当前目录)
print("自定义 enum 模块被导入")

def dummy():
    pass

然后运行一个测试文件:

# main.py
import enum

print(enum)
print(dir(enum))

执行结果:

自定义 enum 模块被导入
<module 'enum' from '/Users/yourname/project/enum.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', 'dummy']

可以看到,Python 确实导入了我们自己定义的 enum.py。所以,系统的 enum.IntFlag 根本没有机会被加载。

正确的解决方案

这个问题的修复其实非常简单,通常有三种做法:

方案一:删除或重命名本地的enum.py

最直接有效的方法就是:

然后重新运行程序,就一切正常了。

方案二:检查__pycache__目录

即使你已经删除了 enum.py,有时候 Python 还会加载缓存文件。

所以建议同时清理掉:

__pycache__/enum.cpython-36.pyc

否则缓存模块仍可能被误导入。

方案三:检查 sys.path 顺序

如果你在多项目环境下开发,可以打印当前解释器的模块搜索路径:

import sys
for p in sys.path:
    print(p)

一般情况下,当前工作目录会排在最前面:

/Users/yourname/project
/usr/local/lib/python3.6
...

你也可以临时调整 sys.path 的顺序(不推荐长期使用):

import sys
sys.path.remove('/Users/yourname/project')

可运行 Demo:验证修复前后效果

我们来做个对比实验,验证修复后的正确行为。

修复前

$ python3
>>> import enum
>>> enum.IntFlag
Traceback (most recent call last):
  ...
AttributeError: module 'enum' has no attribute 'IntFlag'

修复后(删除 enum.py)

$ python3
>>> import enum
>>> enum.IntFlag
<enum 'IntFlag'>

问题成功解决

延伸思考:这个坑不只发生在 enum

这种“本地文件覆盖标准库”的问题非常常见。

开发者最常踩的几个坑还有:

模块名常见误伤结果
enum.py覆盖标准库 enumAttributeError: no attribute
random.py覆盖 random 模块AttributeError: module ‘random’ has no attribute ‘randint’
json.py覆盖 json 模块TypeError: ‘str’ object is not callable
asyncio.py覆盖 asyncio 框架ImportError: cannot import name ‘Future’
logging.py覆盖 logging 模块AttributeError: module ‘logging’ has no attribute ‘getLogger’

总结一句:永远不要用标准库同名文件命名你的模块。

总结

这次的 AttributeError: module 'enum' has no attribute 'IntFlag',并不是 Python 本身的 bug,而是开发环境中“命名冲突”引起的导入遮蔽。

核心要点:

一句话总结:

不是 Python 坏了,是你的文件名太像标准库了。

小贴士

建议你在项目初始化时养成习惯:

这样不仅能避免这类问题,还能让环境更干净,避免未来升级或迁移时出问题。

到此这篇关于Python 3.6.报错 “module ‘enum‘ has no attribute ‘IntFlag‘”的真正原因与解决办法的文章就介绍到这了,更多相关Python module enum has no attribute IntFlag问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文