python基础(13):模块和包
一、模块简介
实际开发中我们不可能不用到系统的标准模块,或第三方模块。
如果想实现与时间相关的功能,就需要调用系统的time模块。如果想实现文件和文件夹有关的操作,就需要用到os模块。再例如我们通过Selenium实现的Web自动化测试,那么Selenium对于python来说就是一个第三方扩展模块。
每个python都可以被当作一个模块。模块以磁盘文件的形式存在。当一个模块变得过大,并且驱动力太多功能的话,就应该考虑拆一些代码出来另外建一个模块。模块里的代码可以是一段直接执行的脚本,也可以是一堆类似库函数的代码,从而可以被别的模块导入(import)调用。模块可以包含直接运行的代码块、类定义、函数定义或这几者的组合。
推荐所有模块在python模块的开头部分导入。而且最好按照这样的顺序:
- python标准库模块
- python第三方模块
- 应用程序自定义模块
导入方式:
在python中用关键字import来引入某个模块,比如要导入模块time,就可以在文件最开始的地方用import time来引入。
import module1
import module2[
……
import moduleN]
或者
import module1[, module2, ……, moduleN]
调用方法:
模块名.函数名
例:
import time
print('start')
time.sleep(5)
print('stop')
# output:输出start后隔5秒再输出stop
from ... import ...
从模块中导入一个指定的部分到当前命名空间中。
from modname import name1[, name2, ... , nameN]
from ... import *
导入一个模块的所有内容。
from modname import *
from ... as ...
有时候你导入的模块名称已经在你的程序中使用了,或者你不想使用现有的名称。可以使用一个新的名称替换原始的名称。
例:
import pandas as pd
二、模块制作
对于一个软件项目来说,不可能把所有代码都放在一个文件中实现,它们一般会按照一定规则在不同的目录和文件中实现。
制作模块:
非常简单,模块即.py文件,里面包含函数、类等,模块名即.py文件名。
调用自己制作的模块:
当你导入一个模块,python解析器对模块位置的搜索顺序是:
- 当前目录
- 当前目录没有,则搜索在环境变量PYTHONPATH下的每一个目录
- 如果都找不到,python会查看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
- 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
引入同级目录下的子模块时:
import 同级文件夹名.文件夹下模块名
引入不同级目录时:
import sys
sys.path.append('..\\') # 返回上一级目录
import modname
所以如果当前路径或PYTHONPATH中存在与标准module相同的module,则会覆盖标准module。也就是说,如果当前目录下存在xml.py,那么在执行import xml时,导入的是当前目录下的module,而不是系统标准的xml.py。
三、dir()函数与标准模块
dir():
dir用于按模块名搜索模块定义,它返回一个字符串类型的存储列表。该列表列出了所有类型的名称:变量,模块、函数等等。
例:
import time
print(dir(time))
输出:['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'altzone', 'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'monotonic_ns', 'perf_counter', 'perf_counter_ns', 'process_time', 'process_time_ns', 'sleep', 'strftime', 'strptime', 'struct_time', 'thread_time', 'thread_time_ns', 'time', 'time_ns', 'timezone', 'tzname']
四、标准模块
有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是却能很高效的使用,甚至是系统级调用也没问题。这些组件会根据不同的早做系统进行不同形式的配置,比如winreg(windows注册表访问)这个模块就只会提供给windows系统。应该注意到这有一个特别的模块sys,它放置在每一个python解析器中。
五、包
- 包是一种管理python模块命名空间的形式,采用“.模块名称”。比如一个模块的名称是A.B,那么它表示一个包A中的子模块B。
- 目录中只有包含一个叫做__init__.py的文件才会被认作是一个包。
- 在导入包的时候,python会从sys.path中的目录来寻找这个包中包含的子目录。
导入包:
现有两个模块功能有些联系,所以将其放到同一个文件夹下,一个文件中的类继承另一个文件中的类。
- 用 import 文件.模块 的方式导入
import modname
- 用 from 文件夹 import 模块 的方式导入
from fname import *
# 导入文件夹内所有模块
制作包:
创建__init__.py时,要注意:
- 目录中只有包含了叫做__init__.py的文件,才能被程序认作是包,模块才能被导入成功。
- __init__.py文件中,要写入一行:__all__ = [允许被导入的模块]
__all__ = ["modname1", "modname2"]
- 可以在__init__.py中编写其他内容,在导入时,这些编写的内容就会被执行。
- 可以在__init__.py中向sys.path添加当前被调用模块路径。
- 不建议在__init__.py中写模块,尽量保证此文件简单。
imp.reload():
例:
import test
# import test # 引入两边只输出一句hahaha
import imp
imp.reload(test) # 此时可以输出两边hahaha