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

 

 

 

  

posted @ 2018-07-17 18:50  auxiaoliu  阅读(521)  评论(0编辑  收藏  举报