Python易学就会(二)import的用法

前文有叙,Python是开放型社群化的开发语言,所以我们在编写Python程序时,不可避免的需要用到别人已经做好的、成型的类库,这些类库可能是图形处理、可能是网络通讯、可能是数据分析等等,反正不需要自己来重新从最底层开始再写一遍,这样就需要用到import 来引入外来的拓展包。
  能否找到更多的第三方库、拓展包,也因此成为评判一个编程语言的开发社区是否活跃、是否易用的一个标志。所以,学会用好import就成为我们学习Python需要重点了解的第一个内容。
  Python能通过import 引入的,有模块(module)和包(package)两种。
  模块(module)的作用,就是可以把一组相关的功能,集成在一个 .py 文件中,方便在其它应用中通过 import 引入来调用。比如跟时间相关的操作,都集成在一个 module 中,使用时这样来操作。

#引入time模块
import time
#调用time模块的sleep()方法
time.sleep(1)

不同人写的模块(module)有可能会重名,例如A写了个time.py模块,B也写了个time.py,他们中间各有一个方法非常好用,对于C来说,就容易混淆了。因此有了包(package)的概念。
  包(package)是在module的外面加了一层,如

#引入A的time模块
import A.time
#引入B的time模块
import B.time
#调用A的time模块的sleep()方法
A.time.sleep(1)
#调用B的time模块的方法
B.time.setTime(0)

就相当于JAVA中的PACKAGE。物理上体现在:模块(module)可以放在同一目录下,而包(package)一般放在以包名命名的文件夹中。下面以例子来解释。

新建 lmModule.py,内容如下

print("From lmModule.py")

运行一下,可以看到正常打印

From lmModule.py

在同一目录中再新建一个main01.py,内容如下

import lmModule

print("From main01.py")

运行一下,可以看到打印出来:

From lmModule.py
From main01.py

由此可见,import实际上是把要导入的程序预先加载在了主程序的前部,两者的内容都得到了执行。

修改一下lmModule.py的内容,添加一个变量和一个方法:

print("From lmModule.py")

lmModule_var = "LmModule Var"

def lmModule_method():
    print("From lmModule.py lmModule_method")

再修改一下main01.py,来尝试调用一下模块的变量和方法:

import lmModule

print("From main01.py")

print(lmModule.lmModule_var)

lmModule.lmModule_method()

运行发现,使用“模块名+.”的方式,可以很好的实现调用,运行结果如下:

From lmModule.py
From main01.py
LmModule Var
From lmModule.py lmModule_method

再次修改main01.py,尝试不同的import方法:

from lmModule import lmModule_var, lmModule_method

print("From main01.py")

print(lmModule_var)

lmModule_method()

用“from 模块名 import 部分变量或方法”这种方式,可以从模块中引入特定的的变量或方法,这些变量或方法可以直接使用,就像程序自己定义的一样,再不需要用“模块名+.”来访问。如果需要引入所有的变量或方法,可以改写成通配符*,执行效果一样。

from lmModule import *

print("From main01.py")

print(lmModule_var)

lmModule_method()

接下来,新建一个目录dir,在dir下面新建一个“dirModule.py”,内容如下:

print("From dir dirModule")

修改main01.py,内容如下,以引入dir目录下的dirModule模块:

from lmModule import *

from dir.dirModule import *

print("From main01.py")

print(lmModule_var)

lmModule_method()

执行发现,把模块定义在下级目录中,也是可以顺利import到的,执行效果如下

From lmModule.py
From dir dirModule
From main01.py
LmModule Var
From lmModule.py lmModule_method

修改dirModule.py,在其中加入一个变量和一个方法的定义,内容如下:

print("From dir dirModule")

lmModule_var = "DirModule Var"

def lmModule_method():
    print("From dir dirModule.py lmModule_method")

执行main01.py,可以看到,当先后import的两个模块中,有相同的变量定义或方法定义时,前面先import的会被后import的覆盖,执行效果如下:

From lmModule.py
From dir dirModule
From main01.py
DirModule Var
From dir dirModule.py lmModule_method

如果修改main01.py,交换import的顺序,可以看到,执行的结果不同,先import的会被后import的覆盖,你可以自己试试。

为避免这种相互覆盖而出错的情况,import 时还是尽量使用“模块名+.”的方式来访问,当然可以用别名。修改main01.py如下:

import dir.dirModule as d

import lmModule as h

print("From main01.py")

print(h.lmModule_var)

d.lmModule_method()

执行效果如下:

From dir dirModule
From lmModule.py
From main01.py
LmModule Var
From dir dirModule.py lmModule_method

在dir目录下新建一个“secModule.py"文件,内容如下:

print("From dir secModule")

secModule_var = "SecModule Var"

修改main01.py,增加对于secModule模块的调用,内容如下:

import dir.dirModule as d
import dir.secModule
import lmModule as h

print("From main01.py")

print(h.lmModule_var)

d.lmModule_method()

print(dir.secModule.secModule_var)

执行一下,可以看到secModule模块的内容正常被引入了,secModule模块中定义的变量也可以使用。

From dir dirModule
From dir secModule
From lmModule.py
From main01.py
LmModule Var
From dir dirModule.py lmModule_method
SecModule Var

好,那么如果想一次性导入dir目录下的多个文件,可行吗,经测试 import dir.* 是不好使的;import dir 更是不好使。那怎么办呢?
  该包(package)上场了!

在dir目录下新建“__init__.py”,内容如下:

from . import secModule
from . import dirModule

有了这个“__init__.py”,就把dir由一个目录,变成了一个包(package)。Python只要在目录下找到这个文件,就会按package来处理,下面我们修改一下main01.py的内容:

import dir
import lmModule as h

print("From main01.py")

print(h.lmModule_var)

dir.dirModule.lmModule_method()

print(dir.secModule.secModule_var)

执行一下,可见通过import一个包dir,可以将包中的所在module都引入进来。执行效果如下:

From dir secModule
From dir dirModule
From lmModule.py
From main01.py
LmModule Var
From dir dirModule.py lmModule_method
SecModule Var

当然__init__.py中也可以定义变量和方法。而且,如果“__init__.py”中包含了变量“__all__”,那么将只有“__all__”中所指定的变量或方法能被外部访问!“__all__”中所指定的变量或方法相当于JAVA中的public。

相关推荐