模块和包

巧了我就是萌 提交于 2020-02-28 10:32:56

导入模块

总结:

import

import 模块名

import 模块名 as 别名

import 模块名1,模块名2,模块名3...(不建议)

from ... import

from 模块名 import 模块文件里具体的功能名字

from 模块名 import 模块文件里具体的功能名字 as 别名

from 模块名 import * (不建议)

#以下两种仅仅针对*号做设置

1> 在模块文件里的功能名字前加_下划线  那么*里就不包含此功能 仅仅针对这里的*

2>在模块文件里设置 __all__['功能名1',“功能名2”...]  仅仅设置的包含在*号里,并不是所有

举例说明:

##重点: 源文件和现文件的名称空间

模块文件

spam.py

 

#spam.py
print('from the spam.py')

money=1000

def read1():
    print('spam->read1->money',money)

def read2():
    print('spam->read2 calling read')
    read1()

def change():
    global money
    money=0

 

 

 

#import导入

import spam
print(spam.money)
print(spam.read1()) #调用的时候 需要加模块名作为前缀
#from ... import  导入

from spam import read1,read2,money
print(read1())
print(money) #直接导入功能名字  可以直接调用

两种方法对比

import  需要添加前缀,但是不容易和当前文件中的变量混淆

from ... import  使用源文件的名字时无需添加前缀,方便 但是容易和当前文件中的名字混淆

查看当然导入的模块

import sys
print(sys.modules)

 

模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下

#test.py
import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
import spam
import spam
import spam

'''
执行结果:
from the spam.py
'''

导入模块做的事

1> 执行源文件

2>以一个源文件的全局名称空间

3>在当前位置拿到一个模块名,指向源文件的名称空间

把模块当做脚本执行

在模块文件的尾部加入以下代码,便于开发者调试,意思是把模块当做脚本执行的时候,才会执行以下代码

当做模块执行的时候  忽略

 

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

 

模块的搜索路径

python解释器在启动时会自动加载一些模块,可以使用sys.modules查看

在第一次导入某个模块时(比如spam),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用

如果没有,解释器则会查找同名的内建模块,如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。

所以总结模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块

为了防止找不到模块,所以要把自定义的模块加入到sys.path路径中 方法如下

import sys
print(sys.path)
sys.path.append(r'F:\untitled\a\b\c')
#或者
sys.path.insert(r'F:\untitled\a\b\c')

导入包

重要点:

1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

强调:

  1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

  2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

 重要: 一定要搞懂,谁是执行文件,执行文件的路径 就是sys.path第一个要找的路径。

导入方式

from 包名(如果有多级目录 包名.二级目录 .三级目录)import 文件名

理念:包也是一种模块,模块就是为了导入使用的 ,要给使用者提供方便

举个例子:

目录结构

 

glance/                   #Top-level package

├── __init__.py      #Initialize the glance package

├── api                  #Subpackage for api

│   ├── __init__.py

│   ├── policy.py

│   └── versions.py

├── cmd                #Subpackage for cmd

│   ├── __init__.py

│   └── manage.py

              #Subpackage for db

 

#文件内容

#policy.py
def get():
    print('from policy.py')

#versions.py
def create_resource(conf):
    print('from version.py: ',conf)

#manage.py
def main():
    print('from manage.py')

如上的目录结构和文件内容,如果想 实现包名.功能名  调用功能的话  那么 glance的 __init__.py  配置如下:

 



from glance.api.versions import create_resource
from glance.cmd.manage import main
from glance.api.policy import get

那么和glance同级目录的执行文件 就可以这样调用

import glance
glance.get()
glance.create_resource('test.conf')
glance.main()

相对导入和绝对导入

依据上边的例子 继续说 (**执行文件和包是同级目录

绝对导入的话 glance的 __init__.py  配置如下:

 

from glance.api.versions import create_resource
from glance.cmd.manage import main
from glance.api.policy import get

 

相对导入:

from .api.versions import create_resource
from .cmd.manage import main
from .api.policy import get
#. 代表当前目录

现在有一个需求 

api/policy.py 需要调用 cmd/manage.py里的功能,那么policy.py里需要增加的配置如下:

绝对导入

from glance.cmd.manage import main #新增内容
def get():
    print('from policy.py')
    main() #新增内容 测试代用manage.py里的main功能

相对导入

from ..cmd.manage import main #新增内容 .当前目录 ..上一级目录
def get():
    print('from policy.py')
    main() #新增内容 测试代用manage.py里的main功能

 

在执行文件里测试 如下

import glance
glance.get()
'''
打印结果:
from policy.py
from manage.py
#两个文件的内容都有了
'''

以上都是基于 执行文件和包在同一目录级别,如果不在同一目录级别 就需要将包的路径加入 sys.path

思路:

导入模块(包)

1> 执行文件如果不和模块(包)在同一目录,就加入到 sys.path里

2>如果是包 就在包的init文件里做好 包的导入

 软件开发规范

 

常用模块

点我查看常用模块

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!