为何Numpy函数在Python Shell初运行正常,后续及脚本执行失败?
你的问题根源完全是因为脚本文件名和Python标准库模块重名了——你把自己的脚本命名为random.py,这直接和Python自带的random模块撞名,引发了模块导入的连锁冲突,具体过程拆解如下:
初次Python Shell运行正常:此时你还没创建
random.py文件,执行from numpy.random import choice时,Python会正常定位到虚拟环境里的numpy模块,内部导入标准库random也不会有干扰,所以一切顺畅。执行
random.py脚本失败:运行脚本时,Python会把当前工作目录加入模块搜索路径的最优先级位置。numpy初始化过程中需要导入标准库的random模块(比如回溯里显示的from random import SystemRandom),但此时Python优先找到了你当前目录下的random.py,而非系统标准库的random。你的脚本里又要导入numpy.random,形成循环导入,同时你的脚本本身不是标准库random模块,自然找不到choice这个属性,因此报错。后续Shell也报错:Python会将已导入的模块缓存到
sys.modules字典中,第一次运行random.py出错后,错误的random模块(你的脚本)已经被缓存。之后在Shell里再导入numpy.random时,Python会直接调用缓存里的错误模块,导致同样的报错。
解决步骤非常直接,按以下操作即可:
第一步:重命名冲突脚本
把random.py改成不会和标准库/第三方模块撞名的名字,比如weighted_choice_demo.py:mv random.py weighted_choice_demo.py第二步:清理模块缓存(建议执行)
删除当前目录下生成的__pycache__文件夹,避免残留缓存干扰后续操作:rm -rf __pycache__第三步:验证修复效果
重启Python Shell(或重新激活虚拟环境),再次执行导入操作:python在Shell中输入:
from numpy.random import choice as weighted_choice此时应该能正常导入,运行重命名后的脚本也不会再报错:
python weighted_choice_demo.py
永远不要给自己的Python脚本命名为和标准库模块、常用第三方模块相同的名字,比如numpy.py、requests.py、json.py等,这类命名冲突会引发各种难以排查的导入错误。
内容的提问来源于stack exchange,提问作者Chuck

