模块
每一个 Python 脚本文件都可以被当成是一个模块,模块可以包含直接运行的代码块、类定义、函数定义或这几者的组合
import
在Python中用关键字import来引入某个模块,也可以在一行内导入多个模块
在调用模块中的函数时,必须加上模块名调用,因为可能存在多个模块中含有相同名称的函数,此时,如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数
''' 输出为 start (延时5秒) stop ''' import time print('start') #sleep(5) 错误调用 time.sleep(5) #正确调用 print('stop')
from...import
Python的from语句能够从模块中导入一个指定的部分到当前命名空间中,使用这种方式导入,不会整个模块导入到当前命名空间,它只会将import的内容导入
from time import sleep print('start') sleep(5) print('stop')
from…import *
导入一个模块的所有内容也可以使用from…import*
#导入模块中的所有内容 from math import * print(ceil(1.1)) #向上取整 输出为2 print(floor(1.1)) #向下取整 输出为1
扩展import语句(as)
有时候导入的模块名称已经在程序中使用了,或者不想使用现有的名称,则可以使用一个新的名称来替换原始的名称,一旦替换后原来的就不可以再用了
#给导入的模块取别名 import math as m print(m.ceil(1.1)) #向上取整 输出为2 print(m.floor(1.1)) #向下取整 输出为1 from math import ceil as c #不建议,函数名最好不要简化或者取别名 print(c(1.1)) #向上取整 输出为2
定位模块
一、当导入一个模块后,Python解析器对模块位置的搜索顺序是:
1、当前目录
2、如果不在当前目录,Python则搜索在环境变量PYTHONPATH下的每个目录
3、如果都找不到,Python会察看默认路径;UNIX下,默认路径一般为/usr/local/lib/python/
模块搜索路径存储在system模块的sys.path变量中(sys模块用于提供对python解释器的相关操作);变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录
二、所以如果当前路径或 PythonPATH中存在与标准模块同样的模块,则会覆盖标准模块;也就是说,如果当前目录下存在xml.py,那么在执行import xml时,导入的是当前目录下的模块,而不是系统标准的xml.py
模块调用
1、引入同级目录中的模块(mian.py和test.py文件在同一级目录)
#mian.py文件 import test #引入同级目录中的test模块 print(test.test_add(2,3)) #输出为5 from test import test_add #两种引入方式 print(test_add(2,3)) #输出为5
#test.py文件 def test_add(x,y): return x+y
2、引入同级目录下的文件夹里的子模块(mian.py和study文件夹在同一级目录,test2.py文件在study文件夹里)
#mian.py文件 import study.test2 #模块名.函数名 print(study.test2.test2_add(2,3)) #输出为5 from study import test2 print(test2.test2_add(2,3)) #输出为5 from study.test2 import test2_add print(test2_add(2,3)) #输出为5
#test2.py文件 def test2_add(x,y): return x+y
3、引入父目录的同级目录的文件夹里的子模块(mian.py的父目录moudle文件夹和msg文件夹在同一级目录,recv.py和send.py文件在msg文件夹里)
#mian.py文件 import sys #查看路径变量 print(sys.path) #添加目标路径导当前环境中 sys.path.append('..\\') #返回上一级目录,(..\\有一组返回一级) print(sys.path) import msg.send msg.send.sendMsg() #输出为 消息发送成功 from msg.recv import recvMsg recvMsg() #输出为 成功接收消息 print('三种不同的实现方式') #输出为 三种不同的实现方式 from msg import send,recv send.sendMsg() #输出为 消息发送成功 recv.recvMsg() #输出为 成功接收消息
#send.py文件 def sendMsg(): print('消息发送成功')
#recv.py文件 def recvMsg(): print('成功接收消息')
4、标准模块的覆盖(mian.py的父目录moudle文件夹和msg文件夹在同一级目录,math.py文件在msg文件夹里)
#mian.py文件 import sys sys.path.append('..\\') #返回上一级目录,(..\\有一组返回一级) import math print(math.ceil(1.1)) #输出为 2 引入的是标准模块 向上取整 print(math.floor(1.1)) #输出为 1 #覆盖标准模块 from msg import math #自定义的模块 #print(math.ceil(1.1)) #程序无法执行,会报错,因为已经被覆盖了 math.getInfo() #输出为 SKT一定要夺冠啊
#math.py文件 def getInfo(): print('SKT一定要夺冠啊')
dir()函数与标准模块
dir()函数一个排好序的字符串列表,内容是一个模块里定义过的名字,返回的列表容纳了在一个模块里定义的所有变量,模块和函数
''' 输出为 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test'] ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test_add'] 双下划线为系统自带 ''' import test print(dir()) print(dir(test))
标准模块:Python 本身带着一些标准的模块库(参考http://www.cnblogs.com/ribavnu/p/4886472.html),有一个特别的模块 sys ,它是内置在每一个 Python 解析器中
包
1、包是一种管理 Python 模块命名空间的形式,采用"点模块名称",比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块B
2、目录中只有包含一个叫做__init__.py的文件才会被认作是一个包
3、在导入包的时候,Python会从sys.path中的目录来寻找这个包中包含的子目录
__init__.py
1、msg文件夹下创建一个__init__.py文件,并且一定要在文件中写入__all__
2、__init__.py 控制着包的导入行为,如果__init__.py文件为空的话,仅仅是把这个包导入,不会导入包中的模块;__init__.py中的__all__变量,是用来控制from包名import * 时导入的模块
3、可以在__init__.py中编写其他内容,在导入时,这些编写的内容就会被执行
4、可以在__init__.py中向sys.path添加当前被调用模块路径
#mian.py文件 import sys #查看路径变量 sys.path.append('..\\') #返回上一级目录 #通过from一次性导入所有的模块 #做一个包一定要创建一个__init__.py 这么文件中一定要设置 __all__ = ['允许导入的模块名'] from msg import * send.sendMsg() #输出为 消息发送成功 recv.recvMsg() #输出为 成功接收消息 math.getInfo() #输出为 SKT一定要夺冠啊
# __init__.py文件 __all__ = ['send','recv','math'] #表示运行被导入的模块send,recv,math
__all__
1、编写Python代码(不建议在__init__中写python模块,可以在包中在创建另外的模块来写,尽量保证__init__.py简单)
2、模块中不使用__all__属性,则导入模块内的所有公有属性、方法和类 ; 模块中使用__all__属性,则表示只导入__all__中指定的属性,因此,使用__all__可以隐藏不想被import的默认值; __all__变量是一个由string元素组成的list变量, 它定义了当我们使用 from 模块 import * 导入某个模块的时候能导出的符号(这里代表变量,函数,类等)注:区别于在包导入中,__all__控制导入的是模块
3、from 模块 import * 默认的行为是从给定的命名空间导出所有的符号(当然下划线开头的变量,方法和类除外), 需要注意的是 __all__ 只影响到了 from 模块 import * 这种导入方式, 对于 from 模块 import 成员 导入方式并没有影响,仍然可以从外部导入
重载——importlib.reload()
默认情况下,模块在第一次被导入之后,其他的导入都不再有效;如果此时在另一个窗口中改变并保存了模块的源代码文件,也无法更新该模块;这样设计原因在于,导入是一个开销很大的操作(导入必须找到文件,将其编译成字节码,并且运行代码),以至于每个文件、每个程序运行不能够重复多于一次
当一个模块被导入到一个脚本,模块顶层部分的代码只会被执行一次;因此,如果想重新执行模块里顶层部分的代码,可以用reload()函数,该函数会重新导入之前导入过的模块
语法如下:
reload(模块名)
#mian.py文件 import test import test #引入两遍只输出一句skt加油 import importlib importlib.reload(test) #重新导入test模块 输出 skt加油