7.2 引入模块

7.2.1 import引用模块

Python使用import语句引用一个模块,这个模块可以是Python内置的模块,也可以是自行编写的模块。

格式为:

import 模块名
或
import 包名.模块名

import引入模块后,对于上面两种引用,分别采用如下方式来使用模块的变量和函数。注意import引入的名称就是模块的完整名称。

模块名.变量名
模块名.函数名
或
包名.模块名.变量名
包名.模块名.函数名

例如有如下目录结构:7.1-module

└─ 7.1-module
   ├─ mymodule.py
   └─ import.py

其中:mymodule.py内容为:

# 被导入的模块
'''
模块的说明部分
'''

myNum = 100

def add100(a):
    return a + 100

import.py内容为:

# 导入Python内置模块
import sys
# 导入自行编写的模块
import mymodule

# 使用模块里面的变量和函数
print(mymodule.myNum)
print(mymodule.add100(20))

# 使用内置模块里面的变量
print(sys.path)

结果为:

100
120
['d:\\Projects\\kejian\\python\\code\\ch07\\7.1-module', 'C:\\ProgramData\\Anaconda3\\python36.zip', 'C:\\ProgramData\\Anaconda3\\DLLs', 'C:\\ProgramData\\Anaconda3\\lib', 'C:\\ProgramData\\Anaconda3', 'C:\\ProgramData\\Anaconda3\\lib\\site-packages', 'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\win32', 'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\Pythonwin']

sys.path结果列表中的第一个元素是当前目录。

7.2.2 from ... import 语句

import引入模块时,是将模块的全部内容引入,如果只想引入其中的一部分,则可以使用from...import语句,从模块中引入所需要的部分。这时可以直接使用引用内容的名称,但是容易和已有模块的内容产生重复,所以应当减少使用。

格式为:

from 模块名 import 函数名或变量名

例如,在上述目录下创建文件:fromimport.py

# 从mymodule模块引入myNum变量
from mymodule import myNum

# 直接用变量名使用引入的内容
print(myNum)
# 这时mymodule模块名没有定义,所以不能使用这种方法。
# print(mymodule.myNum)

# 其它部分不论是直接使用名字或者是模块.名字都不能使用。
# print(add100(20))
# print(mymodule.add100(20))

输出结果为:

100

其它被注释的语句,如果取消注释运行,则会提示模块或者函数名没有定义。

7.2.3 引用包

当把目录加入__init__.py作为包之后,可以引入整个包,或者包中的一个模块。

格式为:

from 包名 import 模块名

假设有如下目录结构:7.2-package

└─ 7.2-package
   ├─ admin
   │  ├─ __init__.py
   │  ├─ edit.py
   │  └─ show.py
   │
   ├─ hr
   │  ├─ __init__.py
   │  ├─ change.py
   │  └─ hire.py
   │
   └─ test.py

其中:edit.py

# admin包中的内容
info = 'Package admin, Module edit'

def printInfo():
    print(info)

show.py

# admin包中的内容
info = 'Package admin, Module show'

def printInfo():
    print(info)

change.py

# hr包中的内容
info = 'Package hr, Module change'

def printInfo():
    print(info)

test.py

# 从包中引入模块
# 方法1:从admin包中引入edit模块
import admin.edit

# 方法2:从admin包中引入show模块
from admin import show

# 引入时要具体到模块
import hr

# edit模块中函数的调用
admin.edit.printInfo()

# show模块中函数的调用
show.printInfo()

# 否则hr将被认为是模块,出现异常
hr.change.printInfo()

输出为:

Package admin, Module edit
Package admin, Module show
Traceback (most recent call last):
  File "d:/Projects/kejian/python/code/ch07/7.2-package/test.py", line 18, in <module>
    hr.change.printInfo()
AttributeError: module 'hr' has no attribute 'change'

如果要引入的包并没有和文件本身在同一个文件夹,则需要将包目录加入到sys.path中,以便于查找到包。

上面目录中的hire.py文件如果要引入admin包中的内容:hire.py

import sys
sys.path.append(r"D:\Projects\kejian\python\code\ch07\7.2-package")

from admin import edit

edit.printInfo()

其中引入sys模块,然后将系统的path路径中添加admin所在的文件夹,然后能够定位admin模块。

输出为:

Package admin, Module edit

这种做法会有一个不符合编程规范的做法,即import语句没有在文件的最开头。如果在PyCharm中可以直接将上一级目录加入包的引入中,例如:

└─ TEAM00
   ├─ test
   │  └─ main.py
   │
   └─ dev
      ├─ __init__.py
      └─ admin.py

test目录下的main.py要引入dev目录下的admin.py时,在main.py中使用:

from Team00.dev import admin

# 下面可以使用admin中的对象

注意:这种方法只能在PyCharm中实现,因为在PyCharm中,Python的环境变量path除了当前文件的目录之外还有项目的目录,所以能够定位到父级目录。其它的编辑器或者命令行下用python执行,还是无法识别目录。

7.2.4 总结

引入同级目录下的模块或同级目录中子目录下的模块,可以直接引入。

引入其他目录下的模块,需要将模块所在目录的路径加入sys.path中。

更好的方式是合理规划好包和模块,让被引入的模块放入引入文件的同级或下级目录中。