Python模块与包

模块(module)

模块module从逻辑上说是一组功能的组合,本质上一个模块就是一个包含Python定义和声明的文件,文件名是模块名字加上.py后缀。

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

使用模块的好处可以大大提高代码的可维护性,其次编写代码也不必再从零开始。当一个模块编写完毕,可以被其它地方引用。使用模块还可以避免函数名和变量名冲突,相同名字的函数或变量完全可以分别存在不同的模块中。

模块导入(import)

模块搜索路径

import mod

当执行import导入模块时解释器都在做什么呢?解释器是如下路径中搜索目标模块的:

  1. 在当前执行文件所在的文件夹中查找是否存在目标模块,若不存在则搜索失败。
  2. 在系统设置的python环境变量指定的路径中搜索
  3. 在python安装时指定的目录下搜索

查看导入模块时的搜索路径

$ python3
>>> import sys
>>> sys.path
[
  '', 
  'D:\\python\\program\\python38\\python38.zip', 
  'D:\\python\\program\\python38\\DLLs', 
  'D:\\python\\program\\python38\\lib', 
  'D:\\python\\program\\python38', 
  'D:\\python\\program\\python38\\lib\\site-packages'
]

如需手工指定路径加入到模块搜索路径可使用

$ python3
>>> abspath = r"D:\\python\\module"
>>> sys.path.append(abspath)
>>> sys.path

模块导入流程

首先会找到需要导入的模块,判断当前模块是否已经被导入过,如果没有导入过则执行导入流程。

导入时先会创建一个属于当前模块的命名空间,如果用户没有定义变量来引用当前模块的内存地址的话,就会使用模块的名称来引用当前模块的内存地址。如果用户使用as来指定变量接收内存地址,接着就会将内存地址赋值给指定变量,此时在后续下文调用时只能使用指定变量进行调用,不能再使用模块名称来调用,调用后执行模块中的代码。

如果模块已经被导入过,解释器不会重新执行模块内的语句,后续import语句仅仅是对已经加载到内存中的模块对象增加一次引用。

模块导入顺序

多个模块导入时可使用逗号分隔,按照规范建议模块导入的顺序为:内置模块 > 第三方扩展模块 > 自定义模块

导入的模块与命名空间

导入的模块会重新开辟一块独立的名称空间,定义在此模块中的函数会把当前模块的命名空间当作全局命名空间,这样当前空间和模块运行空间也就分离开了,互不影响。

模块别名

模块在导入时开辟了新的空间内存,默认使用模块名称来引用新空间的内存地址,有时候模块名称会很长,执行调用模块中的功能时会显得不方便。为了更好地使用模块,可以为模块起别名。在导入模块时,为了不让模块使用默认的名字来引用内存空间,而是由自定义的变量来引用模块的内存地址。

例如:使用变量mn作为模块的别名引用module的引用内存地址

import module_name as mn

对模块指定功能的导入

from ... import

使用from...import导入模块功能时,模块已经全部加载。

绝对导入

绝对导入要给出当前模块、函数的完整路径,import语句使用点号作为分隔符来分隔包或模块。

import ecommerce.products

相对导入

在包存在的情况下如果已经知道父模块的名字可使用相对导入

from .database import Database

如何让Python文件即可以被当作模块来引用,也可以作为脚本来执行呢?

只需要在代码中添加__name__ == ' __main__'判断条件,Python解释器即可知道条件内的为脚本执行的内容。

$ vim mod.py
# coding=UTF-8

list = [100, 200, 300]
str = "hello world"


def fn(x, y):
    print('x = %s, y = %s' % (x, y))


class Klass:
    pass


if (__name__ == "__main__"):
    print(str)
    print(list)
    fn(0, 1)
    obj = Klass()
    print(obj)

模块组织(package)

Python中包package的概念在模块module之上,为了方便管理而将文件进行打包,打包目录下的第一个文件需要是__init__.py,然后是模块和子目录。如果子目录下也存在__init__.py文件则会作为当前包的子包。

引入包为了避免模块命名冲突,简单来说,Python为避免同名模块的问题,引入按文件目录来组织模块的方法,也就是包。

package包是存放在文件夹中的模块集合,包名是文件夹的名字。如果需要告知Python当前文件夹是一个Python的包,需在当前文件夹下创建名为__init__.py的文件。如果没有创建__init__.py文件,就无法从当前文件夹下导入模块。

__init__.py文件的作用

  • Python中作为包的标识不能被删掉
  • 可定义__all__用来模糊导入
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值