彻底搞懂Python中的import与fromimport
对不少 Python 初学者来说,Python 导入其他模块的方式让他们很难理解。什么时候用 import xxx ?什么时候用from xxx import yyy ?什么时候用from xxx.yyy import zzz ?什么时候用from xxx import * ?
这篇文章,我们来彻底搞懂这个问题。
系统自带的模块
以正则表达式模块为例,我们经常这样写代码: import re target = "abc1234xyz" re.search("(d+)", target)
但有时候,你可能会看到某些人这样写代码: from re import search target = "abc1234xyz" search("(d+)", target)
那么这两种导入方式有什么区别呢?
我们分别使用 type 函数来看看他们的类型: >>> import re >>> type(re) >>> from re import search >>> type(search)
如下图所示:
可以看到,直接使用 import re 导入的re 它是一个module 类,也就是模块。我们把它成为正则表达式模块 。而当我们from re import search 时,这个search 是一个function 类,我们称呼它为search 函数 。
一个模块里面可以包含多个函数。
如果在你的代码里面,你已经确定只使用 search 函数,不会再使用正则表达式里面的其他函数了,那么你使用两种方法都可以,没什么区别。
但是,如果你要使用正则表达式下面的多个函数,或者是一些常量,那么用第一种方案会更加简洁清晰。
例如: import re re.search("c(.*?)x", flags=re.S) re.sub("[a-zA-Z0-9]", "***", target, flags=re.I)
在这个例子中,你分别使用了 re.search ,re.sub ,re.S 和re.I 。后两者是常量,用于忽略换行符和大小写。
但是,如果你使用 from re import search, sub, S, I 来写代码,那么代码就会变成这样: import re search("c(.*?)x", flags=S) sub("[a-zA-Z0-9]", "***", target, flags=I)
看起来虽然简洁了,但是,一旦你的代码行数多了以后,你很容易忘记 S 和I 这两个变量是什么东西。
而且我们自己定义的函数,也很有可能取名为sub 或者search ,从而覆盖正则表达式模块下面的这两个同名函数。这就会导致很多难以觉察的潜在 bug。
再举一个例子。Python 的 datetime 模块,我们可以直接import datetime ,此时我们导入的是一个datetime 模块,如下图所示:
但是如果你写为 from datetime import datetime ,那么你导入的datetime 是一个type 类:
因为这种方式导入的 datetime ,它就是Python 中的一种类型,用于表示包含日期和时间的数据。
这两种导入方式导入的 datetime ,虽然名字一样,但是他们的意义完全不一样,请大家观察下面两种写法: import datetime now = datetime.datetime.now() one_hour_ago = now - datetime.timedelta(hours=1) from datetime import datetime, timedelta now = datetime.now() one_hour_ago = now - timedelta(hours=1)
第二种写法看似简单,但实则改动起来却更为麻烦。例如我还需要增加一个变量 today 用于记录今日的日期。
对于第一段代码,我们只需要增加一行即可: today = datetime.date.today()
但对于第二行来说,我们需要首先修改导入部分的代码: from datetime import datetime, timedelta, date
然后才能改代码: today = date.today()
这样一来你就要修改两个地方,反倒增加了负担。
第三方库
在使用某些第三方库的代码里面,我们会看到类似这样的写法: from lxml.html import fromstring selector = fromstring(HTML)
但是我们还可以写为: from lxml import html selector = html.fromstring(HTML)
但是,下面这种写法会导致报错: import lxml selector = lxml.html.fromstring(HTML)
那么这里的 lxml.html 又是什么东西呢?
这种情况常见于一些特别大型的第三方库中,这种库能处理多种类型的数据。
例如 lxml 它既能处理xml 的数据,又能处理html 的数据,于是这种库会划分子模块,lxml.html 模块专门负责html 相关的数据。
自己来实现多种导入方法
我们现在自己来写代码,实现这多种导入方法。
我们创建一个文件夹 DocParser ,在里面分别创建两个文件main.py 和util.py ,他们的内容如下:
util.py 文件: def write(): print("write 函数被调用!")
main.py 文件: import util util.write()
运行效果如下图所示:
现在我们把 main.py 的导入方式修改一下: from util import write write()
依然正常运行,如下图所示
当两个文件在同一个文件夹下面,并且该文件夹里面没有__init__.py 文件时,两种导入方式等价。
现在,我们来创建一个文件夹 microsoft ,里面再添加一个文件parse.py : def read(): print("我是 microsoft 文件夹下面的 parse.py 中的 read函数")
如下图所示:
此时我们在 main.py 中对它进行调用: from microsoft import parse parse.read()
运行效果如下图所示:
我们也可以用另一种方法: from microsoft.parse import read read()
运行效果如下图所示:
但是,你不能直接导入 microsoft ,如下图所示:
你只能导入一个模块或者导入一个函数或者类,你不能导入一个文件夹
无论你使用的是 import xxx 还是from xxx.yyy.zzz.www import qqq ,你导入进来的东西,要不就是一个模块(对应到.py 文件的文件名),或者是某个.py 文件中的函数名、类名、变量名。
无论是 import xxx 还是from xxx import yyy ,你导入进来的都不能是一个文件夹的名字。
可能有这样一种情况,就是某个函数名与文件的名字相同,例如:
在 microsoft 文件夹里面有一个microsoft.py 文件,这个文件里面有一个函数叫做microsoft ,那么你的代码可以写为: from microsoft import microsoft` microsoft.microsoft()
但请注意分辨,这里你导入的还是模块,只不过 microsoft.py 文件名与它所在的文件夹名恰好相同而已。
总结
无论是使用 import 还是from import ,第一个要求是代码能够正常运行,其次,根据代码维护性,团队编码风格来确定选择哪一种方案。
如果我们只会使用到某个模块下面的一个函数(或者常量、类)并且名字不会产生混淆,可识别性高,那么 from 模块名 import 函数名 这没有什么问题。
如果我们会用到一个模块下面的多个函数,或者是我们将要使用的函数名、常量名、类名可能会让人产生混淆(例如 re.S、re.I),那么这种情况下, import 模块名 然后再 模块名.xxx 来调用会让代码更加清晰,更好维护。
但无论什么情况下,都禁止使用 from xxx import * 这种写法,它会给你带来无穷无尽的噩梦。 原文链接:
https://mp.weixin.qq.com/s/tEN1gLPi5PZVAnt0zbrj2Q
苹果系统史诗级大升级,iOS15。4已经来了文明美无限年前本以为手机圈会平平淡淡的度过,没想过苹果又给大家带来了一个炸弹,那就是iOS15。4beta1版,这个版本带来了大家期待已久的戴口罩识别faceID!首先,苹果的iP
山西阳泉有哪些名人?看见这个题目就不自觉地点进来了,可能是一种浓浓的故乡感。首先介绍一下山西阳泉。阳泉市,是山西省地级市,位于山西省东部,是一座新兴工业城市。2012年建成区面积达到105平方公里,三
新加坡新首富身价200亿美元,出生于中国天津亚太日报Hannah据彭博社报道,随着公司股价飙升,新加坡冬海集团联合创始人董事长兼执行长李小冬已成为新加坡首富,身价达到198亿美元。彭博亿万富豪指数显示,冬海集团的美国存托凭证
随着地球温度逐年升高,是不是东北越来越适合人类居住?我是优美生态环境保卫者,很高兴能回答您提出的问题。根据历史记录的气象数据显示,在从19世纪末到现在的一百多年来,全球平均气温的确呈逐渐升高的趋势,而且升温幅度在逐渐加快,这一百多年
为什么感觉wps的用户越来越多,office没人用了?WPS和office是目前我国最大的两个办公软件,其中WPS是国产的,office是微软开发的。这两大办公软件过去30年时间,可以说是恩怨情仇,此起彼伏。微软office是在198
怎么做跨境电商?你确定要知道?我跟着我老板做了2年。我可以粗略的说说。希望给我点点赞关注下谢谢。首先,如果你是个人开设店铺的话我建议你不要做了转国内电商吧。那么我开始进入正题做跨境电商简单来说就是
你见过哪些让你眼前一亮的互联网营销案例?营销说白了就是两句话把产品卖出去,把钱收回来。那么怎么把货卖出去,其实还是要抓住消费群里的心理,要学会换位思考,就是你的产品,你站在消费者的角度考虑一下,需要怎么样才会买单,而且有
大家的苹果7Plus用了几年不卡?在2016年上市期间就入手了,目前已经用了将近3年了,系统依然停留在ios12。4,来说一说目前iphone7plus的使用感受。作为一个3年前的旧款手机,目前使用依然流畅,而苹果
如果老比克出现在这个世界,人类的科技力量能阻止他吗?消灭不掉漫画原作中人类虽然掌握了很多超级先进的科技,比如布里夫博士空间技术的产物万能胶囊,还有满大街跑的悬浮机车等等,但是论军事科技,应该是和现代差不多的水平,或者稍强一些。(漫画
农历二十四节气是谁发明的?闰年又是谁研究出来的?农历二十四节气是谁发明的?闰年又是谁研究出来的?农历二十四节气是颛顼发明的。有人可能不认识颛顼这两个字,颛的意思是圆头胖脑,顼是饰品的意思,合起来就是头戴玉的人。颛顼(zhunx)
今日头条申请认证,与不认证的区别是什么?你好,我是全职自媒体人,很荣幸回答你的问题。以下观点和建议,供参考头条有几个认证,不同的认证,作用不同。不知道你说的哪个,一一给你说下吧。几个认证分别是实名认证,兴趣认证,身份认证