关于python中的import、from、循环引用等相关问题
其他
2020-01-23 12:31:04
阅读次数: 0
摘要
- 关于导包问题,很少有人去在意它,但是它一直都在哪,也许出现了,百度一下就解决了,但是始终不理解。
- 知识不存在不求甚解,授人鱼不如渔。
- 不要拿pycharm中是否有导包提示来考虑此类问题
- 不讨论内置包及第三方包
- 不讨论通过sys.path.insert()方法添加进去的包
先说 from xx import yy 和import xx的区别:
- from:程序进行的修改不会影响到被导入的原模块,且不同程序之间不会互相影响
- import:当出现多个程序导入该模块时,会共用一个模块,程序之间会互相影响,包括原模块。
相对路径导入和绝对路径导入:
- 相对路径:以正在编辑的那个模块为标准去引用
- 绝对路径:以启动文件为标准去引用
再说包和包里的__init__.py:
- __init__和其所在的目录一回事,导入这个包了,就相当于加载并导入这个__init__文件了,所以当你from这个包的时候,除了可以import这个包中的模块,还可以import_init_.py文件中的所有的东西。
- __init__和其所在目录是同一级别的,但是它又确实在这个目录里面,所以想在__init__中导入其所在目录里面的文件的话,需要使用from . import yy的方式。
- 另外,当你使用import导入一个包的时候,只是导入了这个包中__init__文件中的内容,比如:
- import urllib 是不可使用request的,需要import urllib.request,而且这个时候你在使用request的时候,需要用urllib.request.xxx()的方式,而不是request.xxx(),这是因为你导入的是urllib.request,而不是request,urllib.request是一个整体。
- 还有,如果使用 from xx import yy 的话:xx是其启动文件所在目录同级别的别的模块,或者包;而且,当满足下面条件的时候你不可以使用from .xx import yy,必须使用from xx import yy :
- 需要导入xx的模块和xx模块及启动模块在同一级目录中。
然后是循环引用:
- 所谓循环引用,类似死锁:你需要我的时候,我也导入你,下面针对一个常见的应用场景(延迟导入 lazy import)来做处理说明。
- 假设A模块导入B模块,B模块中会使用A模块中的一个变量,那么A模块导入B模块的这个语句一定要放在该变量的下方。
- 这样在B模块导入A模块的这个变量的时候,A 模块已经将这个变量加载出来了,避免循环引用。
- 而且该文件还不能作为启动文件(为什么不能作为启动文件?这个问题我暂时未能解释。)
最后是如何避免循环引用?
- 根本性思想:将循环变为单向。
- 方案推荐:
- 在设计时具有前瞻性(推荐)
- 尝试函数中导入,或者底部导入(lazy import)(较为推荐)
- 尝试使用import导入(较为推荐)
- 重新组织代码 (推荐)
- 合并代码
- 分离代码(设计为类似树状结构)
- 第二三种方法不保证一定成功
补充:建议一些朋友科普一下pep8的导包规范。
发布了55 篇原创文章 ·
获赞 3 ·
访问量 2739
转载自blog.csdn.net/rusi__/article/details/102996322