13-python模块和包

在这里插入图片描述

模块

1. 模块概述

python模块实际就是一个包含了函数和其他语句的python脚本文件,以 .py 文件为后缀名。

文件名即是模块名。

导入模块:

  • import 模块名
    • 调用模块内的函数:模块名.函数名
  • import 模块名 as 新名字
    • 调用模块内的函数:新名字.函数名
  • from 模块名 import 函数名1,函数名2... (用什么函数就导入什么函数)
    • 调用模块内的函数:函数名1函数名2 ……
  • from 模块名 import * (导入模块内的所有函数,由于导入的函数有重名风险,不建议使用)
    • 调用函数方式与上一种相同

2. 自己编写模块

编写一个模块的方式:

先创建一个 .py文件,文件名(即模块名)自己命名,然后打开文件,写入一些函数等语句:

# 模块文件
#文件名称:module_test.py
print('导入测试模块的输出')

name = 'module_test'

def m_t_pr():
    print('调用了模块内的函数m_t_pr()')

调用自己编写的模块:

import module_test as mt #导入模块

mt.m_t_pr()     #调用模块内的函数

print(mt.name)  #使用模块内的变量

3. 模块位置

编写好的模块首先要能被python解释器找到才能导入。

(1)上面自己编写的模块和调用模块的程序应该在同一目录下,这样就能被解释器找到了。如果不在同一目录下,又没有告诉解释器模块的位置(接下来会讲)的话,就会发生异常 ImportError ,即找不到模块位置。

(2)在导入模块是,python解释器首先搜索当前目录下有没有该模块(因此创建python脚本时,脚本文件不要和要在该文件导入的模块重名),如果没有,就会从 sys 模块中的 path变量指定的目录(即python的安装目录和几个子目录,如lib, lib\sitepackages, dlls等)寻找模块,如果还未找到,就会报错。

(3)模块的查找路径可通过 sys模块来进行查看、删减或添加:

import sys

print(sys.path) #查看模块搜索路径,返回一个列表

sys.path.append(模块路径)  #添加模块搜索路径

4. __pycache__ 目录

(1)如果是自己创建的模块,第一次调用完后,模块所在目录会多出一个 __pycache__ 目录,目录下有一个 .pyc 结尾的文件。

(2)实际上这个 .pyc 文件是python把调用的模块编译成字节码的文件。对于模块,python总是在第一次调用后将其编译成字节码的形式,以提高程序启动速度。

(3)另外,python在导入模块时会首先查找有没有该模块的字节码文件,如果存在就将编译后的字节码文件与模块的修改时间对比,如果修改时间不一样,就会重新编译该模块,避免两者内容不一样。

(4)由于python是脚本,如果不想将源文件发布,可以发布编译后的字节码文件,这样可以起到一定的保护源文件的作用。

5. 能独立运行的模块

(1)每个python程序在运行时都有一个 __name__ 属性,通过在程序中对 __name__ 属性的判断,可以让脚本作为模块时和独立运行时都能正确运行。

(2)如果脚本文件是作为模块的,则其 ___name__ 属性会被自动设置为模块名。如果是独立运行的,__name__属性自动被设置为 "__main__" ,因此可以通过 __name__属性来判断程序运行状态。

如下的程序,既可以独立运行,也可以作为模块被另一个程序导入:

#模块文件
#模块名:module_test.py
print('导入模块成功')

name = 'module_test'

def m_t_pr():
    print('使用了模块的函数m_t_pr()')

if __name__ == '__main__':
    m_t_pr()
    print(name)

包概述

包其实就是一个文件夹或目录,但其中必须有一个名为 __init__.py 的文件,这个文件可以是个空文件,仅仅用于表示这个目录是个包。此外,包内还可以嵌套其他一些包。

假如有个包(mywebproj)的结构如下:

mywebproj
	__init.py
	manage.py
	urls.py
	handle/
		__init__.py
		index.py
		info.py
    temple
    	index.html
    	info.html
    tools
    	__init__.py
    	send_email.py
    	graphic.py

导入包里面的模块: 如果要引用子包内的模块,要用 . 依次导入,例如:

导入子包的模块 index.py :

import handle.index

from handle import index

如果 index.py 含有一个函数hdl(),调用方法:

from handle.index import hdl

包详解

(1)上面说 __init__.py 可以是个空文件,只是包的一个标志,实际上第一次导入包的任何部分,都会首先执行 __init__.py 文件的代码,并自动导入其中的变量和函数。

(2)__init__.py的一个作用是对可执行包进行初始化工作,设置 __all__ 变量。

例:(当前目录有个包pack,子包有个 __init__.py 文件)

#__init__.py文件的内容

name = 'aaa'

def pck_test():
    print('bbb')

下面是主程序内容:

import pack         #执行这句后会自动导入 __init__.py里面的变量和函数

print(pack.name)    #输出:aaa

pack.pck.test()     #输出:bbb

(3) 包中同一目录下的模块可以相互引用

  • 例如有个包如下:
qrnd\
	__init__.py
	aaa.py
	bbb.py

#在aaa.py 导入 bbb.py
import subb
  • 包 qrnd 下有两个子包prnnprss在同一个目录下,子包中的模块调用另一个子包的模块:
qrnd\
	__init__.py
    prnn\
    	__init__.py
        ccc.py
        
     prss\
    	__init__.py
        ddd.py

​ 假如在 ccc.py 调用 ddd.py

from qrnd.prss import ddd
  • 如果要调用子包的模块:
qrnd\
	__init__.py
	manage.py
	prnn\
    	__init__.py
        ccc.py

​ 比如manage.py要调用 子包prnn 的模块 ccc.py

from .prnn import ccc.py
posted @ 2020-07-31 20:59  aJream  阅读(39)  评论(0编辑  收藏  举报