python文件命名陷阱

这篇博客讲述了在Python中,将文件命名为与第三方库相同的名称(如`xml.py`)会导致导入错误。博主通过分析Python查找模块的顺序,解释了这是因为Python首先查找当前目录的模块,导致解释器尝试从`xml.py`导入`xml.parsers.expat`,而实际的`xml`模块位于系统的`Lib/xml/parsers`路径下。博主还探讨了文件名与内建模块相同的情况,并通过实践证明在这种情况下不会引发错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学习python,学习到xml部分,按照教程弄了代码,如下:

from xml.parsers.expat import ParserCreate

class DefaultSaxHandler(object):
    def start_element(self, name, attrs):
        print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))

    def end_element(self, name):
        print('sax:end_element: %s' % name)

    def char_data(self, text):
        print('sax:char_data: %s' % text)

xml = r'''<?xml version="1.0"?>
<ol>
    <li><a href="/python">Python</a></li>
    <li><a href="/ruby">Ruby</a></li>
</ol>
'''

handler = DefaultSaxHandler()
parser = ParserCreate()
parser.StartElementHandler = handler.start_element
parser.EndElementHandler = handler.end_element
parser.CharacterDataHandler = handler.char_data
parser.Parse(xml)

运行结果如下:

Traceback (most recent call last):
  File "D:\workspace\python_test_project\test\xml.py", line 1, in <module>
    from xml.parsers.expat import ParserCreate
  File "D:\workspace\python_test_project\test\xml.py", line 1, in <module>
    from xml.parsers.expat import ParserCreate
ImportError: No module named 'xml.parsers'; 'xml' is not a package

百思不得姐,怎么会有错了,网上一搜才知道是我自己的文件名命名为了xml导致,不过,为什么我自己的文件名命名为xml就会导致这个错误呢?这还得结合python查找module顺序来说,python查找module的顺序如下:

1. 首先判断这个module是不是built-in即内建模块,
  如果是则引入内建模块,如果不是则在一个称为sys.path的list中寻找
2. sys.path在python脚本执行时动态生成,包括以下3个部分:
 a.脚本执行的位置,即当前路径
 b.环境变量中的PYTHONPATH, 即.bash_profile
 c.安装python时的依赖位置

而这里的xml属于第三方库不属于内建模块,那么打印下我的sys.pyth看下:

['D:\\workspace\\python_test_project\\test'
 'D:\\workspace\\python_test_project'
 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35-32\\DLLs'
 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35-32\\lib'
 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35-32'
 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35-32\\lib\\site-packages'
 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python35-32\\python35.zip']

可以看到如上面所说,先找的是当前目录,当前目录的文件名我又命名为了xml,所以python解释器会试图从当前的xml.py文件去找xml.parsers.expat,那当然是找不到的了,那么我系统的parsers.expat在哪里呢?找了下路径如下:

%PYTHONPATH%\Lib\xml\parsers

现在我想你知道为什么命名为xml又在里面用到xml模块会报错了。

那么你会说,既然你说当引入非内建的第三方模块时,由于python引入module顺序的原因,文件名不能和使用的第三方模块名一致,那么使用内建模块文件名和内建模块名会报错吗?

就上面的代码添加sys内建模块的引入,然后打印sys.path 将文件名命名为sys:

然后运行下,我们可以看到没任何问题,这就验证了我们上面的说法,当在代码中使用第三方module时,文件名不能和module文一样,在使用内建module的时候没这个限制,有不对的地方欢迎指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值