Python中模块与包有相同名字的处理方法


Posted in Python onMay 05, 2017

前言

在编程开发中,个人觉得,只要按照规范去做,很少会出问题。刚开始学习一门技术时,的确会遇到很多的坑。踩的坑多了,这是好事,会学到更多东西,也会越来越觉得按照规范做的重要性,规范的制定就是用来规避问题的。有时候确实应该听听有经验人的建议,不要一意孤行。这好像不是本文的重点,其实我重点是想表达,尽量按规范做事,这样会少走很多弯路。

我现在使用的主力编程语言是 Python,在接触 Python 至今,我感觉我踩的坑还是极少的,基本上没有遇到什么奇怪的问题。实际上,这并不是一件好事,不踩坑,很多躺在暗处的知识点你不会了解,所以也很难成长。幸好,有一些会踩坑的同事。

一同事问我,在 Python 中,如果一个模块和一个包同名时,是不是只能导入包,如果要导入模块该怎么办。他的意思大概是这样的,在项目的同一级目录下,有一个 foo.py 文件和一个 foo/ 目录,如果 import foo 会导入 foo/ 的内容而不是 foo.py 的内容。

被问到这个问题时,我首先感觉到的是诧异,这明显是存在歧义的。如果是我,肯定不会把模块名和包名设计成一样的名字,因为本质上来说在导入的时候没法区分到底要导入谁。除非系统有特别的规定,例如,规定这种情况只能导入包。

我的潜意识里认为这里应该报错,Python 解释器不知道要导入谁。但是,同事告诉我,别人的代码是这么写的,而且在这种情况下会默认导入包。那就是可以的咯,而且解释器已经规定这种情况会总是导入包。

为了验证下这一点,我写了个简单的项目,项目结构如下:

.
├── main.py
└── same
 ├── api
 │ └── __init__.py
 ├── auth
 │ └── __init__.py
 ├── auth.py
 └── __init__.py

其中:

same/api/__init__/py 的内容:

from .. import auth

same/auth/__init__.py 的内容:

auth_str = "This is str in package!"

same/auth.py 的内容:

auth_str = "This is str in module!"

main.py 的内容:

from __future__ import print_function

from same.api import auth

# Script starts from here

if __name__ == "__main__":
 print(auth.auth_str)

稍微有些复杂,哈哈,主要是同事那儿大致的结构是这样的,这里是为更好的模拟下。我在 same.auth 包中定义了一个 auth_str 字符串,又在同名的 same.auth 模块中定义了一个同名的 auth_str 字符串,然后在 same.api 包尝试导入 auth,最后在 main.py 尝试输出 same.api.auth.auth_str,看看到底哪个字符串会被打印。同时尝试用 Python2 和 Python3 执行 main.py,得到的结果都是:

This is str in package!

这里验证了我们的猜想是正确的,解释器的确只导入了包中内容。但是,我并不知道是否有官方的资料说明就是这样的,所以我不敢确信,万一这只是巧合呢。

于是,我开始查资料来验证这一结论。我就说实话吧,对于一个英文水平烂到你无法想象的我,只能先尝试用百度搜索下答案了。事实是,用百度往往都是遗憾的。片刻后,无果,我只能硬着头皮尝试英文搜索了。于是,在 stackoverflow 上找到了如下提问:

How python deals with module and package having the same name?

其中有一个人回答说 Python 官方文档中在描述模块搜索路径时提到了这一点:https://docs.python.org/3/tutorial/modules.html#the-module-search-path.

文档中有如下一段描述:

After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended. See section Standard Modules for more information.

也就是说,目录在库的搜索路径下会首先被搜索,这就意味着目录会代替同名的模块被加载。

这下终于放心了,之前的结论得到证实。在 Python 中,如果尝试导入同名的模块和包时,包会被导入。这种情况下,如果想要导入模块,恐怕要用一些 ‘hack' 的方法,上面提到的 stackoverflow 帖下有一些示例可以参考。当然,最好的方法是避免这样的设计,这样你就不会花那么长时间去查资料,也不会花那么长时间来写类似于本文的文章。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python translator使用实例
Sep 06 Python
python实现马耳可夫链算法实例分析
May 20 Python
python模块简介之有序字典(OrderedDict)
Dec 01 Python
Python编程之变量赋值操作实例分析
Jul 24 Python
Django教程笔记之中间件middleware详解
Aug 01 Python
详解python实现交叉验证法与留出法
Jul 11 Python
python+logging+yaml实现日志分割
Jul 22 Python
opencv转换颜色空间更改图片背景
Aug 20 Python
在pycharm中文件取消用 pytest模式打开的操作
Sep 01 Python
pycharm激活码2020最新分享适用pycharm2020最新版亲测可用
Nov 22 Python
Python 中如何使用 virtualenv 管理虚拟环境
Jan 21 Python
教你怎么用python实现字符串转日期
May 24 Python
详解python 字符串和日期之间转换 StringAndDate
May 04 #Python
Pycharm学习教程(7)虚拟机VM的配置教程
May 04 #Python
python 统计代码行数简单实例
May 04 #Python
利用PyInstaller将python程序.py转为.exe的方法详解
May 03 #Python
Pycharm学习教程(6) Pycharm作为Vim编辑器使用
May 03 #Python
利用numpy+matplotlib绘图的基本操作教程
May 03 #Python
利用matplotlib+numpy绘制多种绘图的方法实例
May 03 #Python
You might like
PHP简单实现“相关文章推荐”功能的方法
2014/07/19 PHP
php调用mysql存储过程实例分析
2014/12/29 PHP
Yii实现多数据库主从读写分离的方法
2014/12/29 PHP
朋友网关于QQ相关的PHP代码(研究QQ的绝佳资料)
2015/01/26 PHP
PHP实现算式验证码和汉字验证码实例
2015/03/09 PHP
php查询mysql数据库并将结果保存到数组的方法
2015/03/18 PHP
PHP实现的大文件切割与合并功能示例
2018/04/10 PHP
关于laravel5.5的定时任务详解(demo)
2019/10/23 PHP
javascript 函数式编程
2007/08/16 Javascript
通过隐藏option实现select的联动效果
2009/11/10 Javascript
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
2009/12/03 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法
2014/12/20 Javascript
javascript实现鼠标放上后下边对应内容变换的效果
2015/08/06 Javascript
jquery事件绑定解绑机制源码解析
2016/09/19 Javascript
ajax与json 获取数据并在前台使用简单实例
2017/01/19 Javascript
Vue2组件tree实现无限级树形菜单
2017/03/29 Javascript
深入理解vue中的$set
2017/06/01 Javascript
4个顶级JavaScript高级文本编辑器
2018/10/10 Javascript
[59:44]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 paiN vs iG
2018/03/31 DOTA
[01:10:27]DOTA2-DPC中国联赛正赛 SAG vs XG BO3 第二场 3月5日
2021/03/11 DOTA
Python实现截屏的函数
2015/07/25 Python
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
2017/07/30 Python
Python爬虫获取图片并下载保存至本地的实例
2018/06/01 Python
Django--权限Permissions的例子
2019/08/28 Python
python3.6.5基于kerberos认证的hive和hdfs连接调用方式
2020/06/06 Python
python判断字符串以什么结尾的实例方法
2020/09/18 Python
韩国著名的在线综合购物网站:Akmall
2016/08/07 全球购物
六五普法规划实施方案
2014/03/21 职场文书
说明书范文
2014/05/07 职场文书
优秀员工评优方案
2014/06/13 职场文书
个人先进事迹材料范文
2014/12/29 职场文书
食品安全主题班会
2015/08/13 职场文书
2016年社区六一儿童节活动总结
2016/04/06 职场文书
​(迎国庆)作文之我爱我的祖国
2019/09/19 职场文书
Python的代理类实现,控制访问和修改属性的权限你都了解吗
2022/03/21 Python