python规范模块和包
主要内容:
1.模块
2.包
1.模块
模块分为三种:
1)内置模块
2)扩展模块
3)自定义模块
3)自定义模块
模块的创建 导入 模块名
创建:
1. 注意 模块名 需要符合变量命名规范
2. 导入模块的时候,pycharm的报错提示是不可靠的
3. 导入一个模块 就是import 文件名 不带.py
导入:
import 导入,
1.相当于执行了这个被导入的py文件.
2. 这个模块不会被重复导入
3.内存中所有被导入的模块都会存储在sys.modules字典中,注意这个字典的key是这个模块的名字,value是这个模块的内存地址.
import test,sys print(sys.modules["test"])
4.模块导入之后,可以直接使用这个模块的函数和变量,使用示例如下:
import sys import test print(test.name) test.A()
模块的命名空间
每一个模块的导入都会创建一个属于自已的命名空间.
在导入模块的时候发生了什么?
1. 创建一个属于这个模块的命名空间.
2.执行这个模块中的代码 .
3. 创建一个引用来调用这个模块命名空间中的名字
4.把导入的模块和内存地址存到sys.modules中
给导入的模块重命名:
import my_module as m
1. 可以给导入的模块进行重命名,重命名之后新的名字会出现在内存空间中来作为模块的引用
2.但是原模块名就不能在文件中使用了
导入多个模块:
要注意两点:
1. 都写在文件的开始
2.顺序:先导入内置的,再导入扩展的,然后再导入自定义的.
from import 导入:
1. 和import一样,这个导入,相当于执行这个模块.
2. 仍然会把模块中所有的名字存在一个属于这个模块的命名空间中.
3.区别在于使用模块中的名字时候,不需要再带着模块名.而是导入了什么名字就能用什么名字
4.没有导入的名字不能使用.
导入多个名字和重命名语法:
from my_module import flag as f,read1 as r1
如果模块中的方法和变量较多的话,可以用下面的方法:
from my_module import *
这个是导入所有的变量和方法(不推荐使用,可能会对本程序照成干扰.)照成干扰的示例如下:
# from import * # def time(): # print('time.time') # from my_module import * # time()
from modules import * 和__all__的关系.
如果导入的模块中有__all__那么from modules import * 时,这个*只表示__all__指定的内容的.
# __all__只和*相关
# 如果不定义__all__,默认*可以导入这个模块中的所有名字
# 如果定义了__all__,那么只有出现在all这个列表中的名字可以被*导入
模块的加载和修改:
模块的一旦导入,模块的内容就在内存当中,此时你再修改文件是没有效果的.除非您用下面的方法.
import time import importlib import test print(test.name) time.sleep(20) importlib.reload(test) # 测试 print(test.name)
把模块当脚本执行
# __name__是py文件中的一个内置的变量,如果单独执行这个py文件,__name__值为__main__,如果这个py文件被其他文件导入的话,那么__name__ 就是这个文件名了.
# __name__是py文件中的一个内置的变量
# 当你直接执行这个py文件的时候,这个文件中的__name__就是'__main__'
# 当你以模块的形式导入这个py文件的时候,这个文件中的__name__就是模块名的字符串
# __file__
if __name__ == '__main__':
# 写在这段代码下面的所有内容只有在当前py文件被直接run的时候才会执行
# 被导入的时候不会被执行
pass
# main # table会自动补全
模块搜索路径:
导入模块后,是通过import sys, sys.path里面的路径来搜索模块的,如果没有就会报错.
# import sys # print(sys.path) # 导入模块的时候,从这个列表中的目录下去找 # sys.path.append(r'E:\sylar\python_workspace\day31\homework') # import core # core.login()
包:
带着__init__.py的文件夹就是包.包里面可以放很多文件和文件夹.
参考如下
目录截图如上,如果在测试.py中想导入policy.py文件引用里面的get()函数的话,
1.可以用import 来导入,如下:
import glance.api.policy #注意只有为包时,才能用.导入 glance.api.policy.get()
或者如下导入
import glance.api.policy as policy #注意这里只能也必须精确到模块
policy.get()
2.用from import来导入,参考如下:
from glance.api import policy policy.get()
import 导入时凡是导入时带点的,点的左别都必须是一个包.
from import导入时必须是明确的一个不能带点的,否则会有语法错误.比如from mymodule import b.c会报错
import 包时,如果导入的是一个包的名字而不是一个py文件的名字.就会直接执行这个包下面的__init__.py除此之外什么也不会做.
关于包的绝对导入:
比如上图,我这里导入import glance,为了能调用get()方法,那么我需要在glances的__init__.py里面加入from glance import api 以及api的文件夹的__init__.py文件里面加入from glance.api import policy. 这个的问题是,如果glance换个目录的话,那么__init__.py里面的值就要更改.
关于包的相对导入:
还是上面的问题,如果是相对导入的话,__init__.py里的内容可以改为from . import api 和 from . import policy.
但是使用相对导入,不能直接执行使用了相对导入的文件.# 必须将这个存在着相对导入的包作为一个整体来使用.
# 只有你写了一个包
# 这个包对外提供功能,而不是用来直接执行这个包中的某个py文件的时候才会用到相对导入
关于包导入的时的*和__all__问题:
glance/ ├── __init__.py from .api import * from .cmd import * from .db import * ├── api │ ├── __init__.py __all__ = ['policy','versions'] │ ├── policy.py │ └── versions.py ├── cmd __all__ = ['manage'] │ ├── __init__.py │ └── manage.py └── db __all__ = ['models'] ├── __init__.py └── models.py import glance policy.get() import glance