目录
1.系统自带模块库
2.第三方库
3.自定义函数库
在Python编程中经常会使用到import,那么什么时候使用import xxx?什么时候使用from xxx import mmm?什么时候使用from xxx.mmm import yyy?什么时候使用from mmm import *???
在 python 用 import 或者 from...import 来导入相应的模块。
将整个模块(somemodule)导入,格式为: import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为: from somemodule import *
首先来看一下系统自带的模块,以正则表达式为例,经常写代码:
import re
example = '1am24tr';
re.search('(\d+)',example);
有的时候也可能这样写:
from re import search
example = '1am24tr';
search('(\d+)',example);
为什么两种导入的方式不同,代码也会有所不同呢?在Python解释器中使用type函数来分别查看他们的类型,如下所示:
import re
type(re)
from re import search
type(search)
如图所示:
根据结果可知,直接使用import re写法导入的re它是一个mdule类,也就是常说的模块,我们把它称为正则表达式。而使用from re import search写法时,这个search它是一个function类,称之为search函数。一个模块里面有可以有许多个函数。如果在代码里面已经确定只适用了search函数,不会在使用正则表达式里面的其它函数时,你可以使用这两种方法都可以,没有什么区别;但是如果你使用正则表达式下的多个函数,或者一些常量,那么使用import re会更加的方便清晰。
例如:
import re
re.search();
re.sub();
以上的例子就是在re中分别使用了re.search、re.sub。但是如果使用from re import search,sub来写代码,就会变成:
from re import search,sub
search();
sub();
如果自己定义的函数名字为search、sub时,可能会混淆,从而会覆盖正则表达式模块下的这两个同名的函数,会导致很多bug存在。
如Python中的datatime模块,可以直接使用import datatime,此时导入的是一个datetime模块,如下图所示:
datetime是一个module类,如果写成from datetime in 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用于记录今天的日期,则只需要:
第一种:
import datetime
now = datetime.datetime.now()
one_hour_ago = now - datetime.timedelta(hours=1)
today = datetime.date.today()
第二种:
from datetime import datetime, timedelta,date
now = datetime.now()
one_hour_ago = now - timedelta(hours=1)
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它既能处理xml的数据,又能处理html的数据,于是这种库会划分子模块,lxml.html模块专门负责html相关的数据。
我们也可以自己编写函数,从而导入;首先创建一个文件夹python_work,在里面分别建立两个文件hanshu.py和multil.py,他们的内容分别是:
multil.py:
def write():
print('write 函数被调用!')
hanshu.py:
import multil
multil.write()
将hanshu.py中的内容修改一下得:
from multil import write
write()
这样也是可以的,同时在multil.py中添加一个函数:
def write():
print('write 函数被调用!')
def read():
print('read 函数被调用!')
如果我们在建立一个名为PYTHON_WORK文件夹,并且在PYTHON_WORK中添加一个duqu.py,并编写一个read函数,即:
duqu.py:
def read():
print('read 函数被调用!')
在hanshu.py中调用read函数时,即:
from PYTHON_WORK import duqu
duqu.read()
也可以使用另外一种方法即:
from PYTHON_WORK.duqu import read
read()
但是不能直接导入PYTHON_WORK,如下所示这样会出错的:
import PYTHON_WORK
PYTHON_WORK.duqu.read()
你只能导入一个模块或者导入一个函数或者类,不能导入一个文件夹。无论你是使用import mmm还是from mmm.xxx.yyy.aaa import zzz,你导入的对象要不是一个模块(对应于.py文件的文件名),或者是某个.py文件夹中的函数名、类名、变量名。使用import mmm导入时,mmm是必须一个模块,不能是函数或者类名、变量名等.
无论是import mmm还是from mmm import aaa,你导入进来的都不能是一个文件夹的名字。可能有一种情况就是某个函数名与文件夹名字相同,例如:
在PYTHON_WORK文件下有个PYTHON_WORK.py文件,这个文件下有一个read函数,则可以写成:
from PYTHON_WORK import PYTHON_WORK
PYTHON_WORK.read()
无论使用import还是from import,第一个要求是代码能够正常运行,其次,根据代码维护性,团队编码风格来确定选择哪一种方案。如果只会使用到某个模块下面的一个函数(或者常量、类)并且名字不会产生混淆,可识别性高,那么from模块名import函数名这没有什么问题。