点击上方“Python编程时光”,选择“加为星标”第一时间关注Python技术干货!明哥原创的200页《PyCharm 中文指南》 震撼发布

Python凭什么就那么好用呢?

毫无疑问,大量现成又好用的内置/第三方库功不可没。

那我们是怎么使用它们的呢?

噢,对了~是用的import xxx这个语句。

之所以会有此一问,也是之前有一次使用PyCharm进行开发时(又)踩了个坑……


废话少说,先讲问题

像下面这样一个项目结构:

Projetc_example|-- A   |-- alpha.py   |-- beta.py|-- B    |-- theta.py|-- main    |-- main.py

假设要在main.py中导入theta.py

# main/main.pyfrom B import theta

显然会导致我们所不希望的问题,即Python不知道要到哪里去找这个名为B的模块(包是一种特殊的模块):

Traceback (most recent call last):  File "main/main.py", line 1, in     from B import thetaModuleNotFoundError: No module named 'B'

可是这就奇了怪了,为啥同样的代码,在PyCharm里运行就是好的了呢?

import的查找路径

于是我们不辞艰辛,上下求索,原来在Python中,import语句实际上封装了一系列过程。

1. 查找是否已导入同名模块

首先,Python会按照import xxx中指定的包名,到sys.modules中查找当前环境中是否已经存在相应的包——不要奇怪为什么都没有导入sys这个模块就有sys.modules了。

sys是Python内置模块,也就是亲儿子,导入只是意思一下,让我们这样的外人在导入的环境中也可以使用相关接口而已,实际上相应的数据对Python而言从始至终都是透明的。

我们可以导入sys查看一下这个对象的具体内容(节省篇幅,做省略处理):

>>> import sys>>> sys.modules{'sys': , 'builtins': , ...'re': , ...}

这些就都是Python一开始就已经加载好的模块,也就是安装好Python之后,只要一运行环境中就已经就绪的模块——只是作为外人的我们还不能直接拿过来用,得跟Python报备一声:“欸,我要拿您儿子来用了嗨~”

很容易可以发现,sys.modules中列出来的已加载模块中存在明显的不同,前面的很多模块显得很干净,而后面的很多模块都带有from yyy'的字样,并且这个yyy看起来还像是一个路径。

这就关系到我们接下来要讲的步骤了。

2. 在特定路径下查找对应模块

前面我们讲到了,当我们导入某个模块时,Python先会去查询sys.modules,看其中是否存在同名模块,查到了那当然皆大欢喜,Python直接把这个模块给我们用就好了,毕竟儿子那么多,借出去赚点外快也是好事儿不是?

可问题在于:那要是没找到呢?

这显然是一个很现实的问题。毕竟资源是有限的,Python不可能把你可能用到的所有模块全都一股脑给加载起来,否则这样男上加男加男加男……谁也顶不住啊不是(大雾


于是乎就有人给Python出了个主意:那你等到要用的时候,再去找他说他是你儿子呗

Python:妙哇~


有了这个思路,Python就指定了几家特定的酒楼,说:“凡是去消费的各位,都可以给我当儿子。”

就这样,一些本来不是Python亲儿子的人,出于各种原因聚集到了这几家酒楼,以雇佣兵的身份随时准备临时称为Python的儿子。

这可就比周文王开局就收100个义子优雅多了,养家糊口的压力也就没那么大了(Python:什么?我的亲儿子都不止100个?你说什么?听不见啊——


回到正经的画风来——

实际上,在Python中,sys.path维护的就是这样一个py交易的结果~~(诶?好像莫名发现了什么),其中保存的内容就是这几家“指定酒楼”,也就是当Python遇到不认识的儿子~~模块时,就会去实地查找的路径。

我们也可以打印出来看看具体内容:

>>> sys.path['', 'E:\\Anaconda\\Anaconda\\python37.zip', 'E:\\Anaconda\\Anaconda\\DLLs', 'E:\\Anaconda\\Anaconda\\lib', 'E:\\Anaconda\\Anaconda', 'E:\\Anaconda\\Anaconda\\lib\\site-packages', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\win32', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\win32\\lib', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\Pythonwin']

大体上就是安装环境时配置的一些包所在路径,其中第一个元素代表当前所执行脚本所在的路径。

也正是因此,我们可以在同一个目录下,大大方方地调用其他模块。

3. 将模块与名字绑定

找到相应的非亲生模块还没完,加载了包还得为它分配一个指定的名字,我们才能在脚本中使用这个模块。

当然多数时候我们感知不到这个过程,因为我们就是一个import走天下:

import sysimport osimport requests

这个时候我们指定的模块名,实际上也是指定的稍后用来调用相应模块的对象名称。

换个更明显的:

import requests as req

如果这个时候只使用了第二种方式来导入requests这个模块,那么很显然在之后的程序流程中,我们都不能使用requests这个名字来调用它而应当使用req

这就是Python导入过程中的名称绑定,本质上与正常的赋值没有太大区别,加载好了一个对象之后,然后为这个对象赋一个指定的变量名。

当然即使是已经加载好的模块,我们也可以利用这个名称绑定的机制为它们取别名,比如:

>>> import sys>>> import sys as sy>>> sys.path['', 'E:\\Anaconda\\Anaconda\\python37.zip', 'E:\\Anaconda\\Anaconda\\DLLs', 'E:\\Anaconda\\Anaconda\\lib', 'E:\\Anaconda\\Anaconda', 'E:\\Anaconda\\Anaconda\\lib\\site-packages', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\win32', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\win32\\lib', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\Pythonwin']>>> sy.path['', 'E:\\Anaconda\\Anaconda\\python37.zip', 'E:\\Anaconda\\Anaconda\\DLLs', 'E:\\Anaconda\\Anaconda\\lib', 'E:\\Anaconda\\Anaconda', 'E:\\Anaconda\\Anaconda\\lib\\site-packages', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\win32', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\win32\\lib', 'E:\\Anaconda\\Anaconda\\lib\\site-packages\\Pythonwin']>>> sys == syTrue

问题解决

好了,上面就是对Python导入机制的大致介绍,但是说了半天,我们的问题还没有解决:在项目中如何简洁地跨模块导入其他模块?

在使用PyCharm的时候倒是一切顺遂,因为PyCharm会自动将项目的根目录加入到导入的搜索路径,也就是说像下面这样的项目结构,在任意模块中都可以很自然地通过import A导入模块A,用import B导入模块B。

Projetc_example|-- A   |-- alpha.py   |-- beta.py|-- B    |-- theta.py|-- main    |-- main.py

但是在非IDE环境中呢?或者说就是原生的Python环境中呢?

很自然地我们就会想到:那就手动把项目根目录加入到sys.path中去嘛。说起来也跟PyCharm做的事没差呀

可以,贫道看你很有悟性,不如跟我去学修仙吧

所以我们就通过sysos两个模块七搞八搞(这两个模块以前有过介绍,不再赘述)——

噔噔噔噔——好使了

# Peoject_example/A/alpha.pyprint("name: " + __name__)print("file: " + __file__)

def al():    print("Importing alpha succeeded.")

main.py中则加入一个逻辑,在sys.path中增加一个项目根目录:

import osimport sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

import A.alpha

A.alpha.al()

# name: A.alpha# file: *\Project_example\A\alpha.py# Importing alpha succeeded.

大功告成,风紧扯呼~

总结

本文借由一个易现问题引出对Python导入机制的介绍,实际上限于篇幅,导入机制只是做了一个概览,具体的内容还要更加复杂。本文讲到的这三步则适用于比较常见的情形,了解了这三步也足以应付很多问题了。更多内容还是留待大家自行探索,当然后续也可能会有文章进一步讲解——谁知道呢哈哈~~(又挖坑了)~~

参考资料

https://docs.python.org/zh-cn/3/reference/import.html

对了,看完记得一键四连,这个对我真的很重要。

推荐阅读

明哥写的200页《PyCharm 中文指南》终于发布了《Python黑魔法指南》全新版本 v2.0 上线发布Python时间模块,超实用总结!手机没网了,却还能支付,这是什么原理?新一代 Notebook 的神器出现,替代 JuPyter 指日可待要搞懂元类(metaclasses),这篇文章一定要看弄懂这 6 个问题,拿下 Python 生成器!数字证书、签名到底是什么?这篇文章讲得太好了

长按下图  ➡   关注博主

(按左边关注 Python, 按右边关注 Goalng)

import sys是什么意思_学了半天,import 到底在干啥?相关推荐

  1. python如何自学模块_跟老齐学Python之Import 模块

    认识模块 对于模块,在前面的一些举例中,已经涉及到了,比如曾经有过:import random (获取随机数模块).为了能够对模块有一个清晰的了解,首先要看看什么模块,这里选取官方文档中对它的定义: ...

  2. python n个list如何组成矩阵_学完Python,我决定熬夜整理这篇总结...

    来源:http://suo.im/5wzRqt 前言:学完Python,我决定熬夜整理这篇总结- 一.了解Python Python之父 Guido Van Rossum,一位荷兰程序员,在1989年 ...

  3. 学了半天,import 到底在干啥?

    文 | 轩辕御龙 来源:Python 技术「ID: pythonall」 Python凭什么就那么好用呢? 毫无疑问,大量现成又好用的内置/第三方库功不可没. 那我们是怎么使用它们的呢? 噢,对了~是 ...

  4. 学计算机应用好还是汽车维修好,大学汽车运用与维修专业怎么样_学什么_前景好吗-520吉他网...

    时间:2019-06-23     来源:网络资源 汽车运用与维修专业怎么样_学什么_前景好吗 2019高考填报志愿时,汽车运用与维修专业怎么样.学什么.前景好吗等是广大考生和家长朋友们十分关心的问题 ...

  5. python之sys模块详解_(转)python之os,sys模块详解

    python之sys模块详解 原文:http://www.cnblogs.com/cherishry/p/5725184.html sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和 ...

  6. 系统相关的信息模块: import sys

    系统相关的信息模块: import sys sys.argv 是一个 list,包含所有的命令行参数. sys.stdout sys.stdin sys.stderr 分别表示标准输入输出,错误输出的 ...

  7. 笨方法学python之import sys与from sys import argv的区别

    这是在网上看到的一个大神的解答: sys is a module that contains "system functionality". sys.argv is a list ...

  8. python from sys import argv_笨方法学python之import sys与from sys import argv的区别

    sys is a module that contains "system functionality". sys.argv is a list containing your s ...

  9. python3命令需要使用命令行开发者工具_关于Python3的import问题(pycharm可以运行命令行import错误)...

    以前从来没有写过特别多的代码,这次在阅读论文的时候跑别人的代码的时候出现了很多import的问题,这里我想跟大家分享一下,我在Ubuntu系统,使用的是anaconda3,版本为3.6,我一般会在py ...

  10. java在容器中导入图片_Java程序员必学技术:@Import直接导入类,在容器@Configuration、@Component中是怎么直接导入类注册到容器的?...

    Java程序员必学技术:@Import直接导入类,在容器@Configuration.@Component中是怎么直接导入类注册到容器的? Spring IoC 容器是一个管理 Bean 的容器,在 ...

最新文章

  1. 【Netty】大白话 Netty 核心组件分析
  2. 报告|机器人行业深度报告:机器人产业价值与回报相关度分析
  3. python提取部分字符串三参数_Python3字符串
  4. UVa11855 Buzzwords(hash)
  5. java a[i].setx(-1);_java – setX和setY在尝试定位图像时不起作用
  6. css的一种预处理器 sass
  7. 集设作品灵感|App夜间模式如何设计?
  8. Gensim官方教程翻译(二)——主题与转换(Topics and Transformations)
  9. AAC Explicit or Implicit SBR PS issue
  10. Synchronized的底层实现原理(看这篇就够了)
  11. REST是否会步SOAP的后尘?
  12. 下载pyboard的flash中的驱动程序_HASP加密狗驱动程序没有安装成功如何解决
  13. 怎样用计算机计算矩阵,【活用工具】教你如何用卡西欧fx82es计算机计算复数 矩阵等...
  14. 80386异常和中断
  15. 2022年信息安全从业者书单推荐(2022.2.20更新)
  16. 巴菲特致股东的信pdf_巴菲特历年股东大会股东信问答实录集合(共7份)
  17. 单件模式(Singleton Pattern
  18. 3d打开无法下载star.php,下载的3dmax模型打开失败的原因及解决方法
  19. python word 表格宽度_RPA手把手——python-docx 设置 word 文档中表格格式
  20. 最小生成树问题:算法分析 Java 实现

热门文章

  1. DPM2012学习(二),添加本地磁盘
  2. bzoj 3196二逼平衡树 线段树套平衡树
  3. 多态和C++多态的实现(汇总)
  4. Ubuntu 下 MySQL 数据自执行备份
  5. SpringBoot 分布式session
  6. Ubuntu tomcat
  7. 合并多个js,css文件的方法 - 在服务端合并和压缩JavaScript和CSS文件
  8. python rest 框架,[Python自学] restframework
  9. 电脑无线网络显示红叉_Maxidix Wifi Suite下载_无线网络管理软件中文版v14.5.8
  10. 拓端tecdat|R语言区间数据回归分析