模块和包

Module模块

为什么使用模块

  • 模块是一种组织代码的形式,它用文件的形式,将函数、变量组织起来。
  • 大大提高了代码的可维护性
  • 编写代码不必从零开始

模块的两个方向

  • 用于执行
  • 用于被调用(没有执行效果)

调用模块的方式

  • import module1
    import module2
  • import module1, module2

以上更推荐第一种,代码可读性更强。
另外在调用时,也可以给模块重新命名:import module as module_name
当我们在当前脚本import module时,解释器会自动把当前脚本所在的目录加入到sys.path的第一个位置,然后在sys.path的所有路径中搜寻模块。

import的两个过程

  • 创建一个新的名称空间,用于存放模块中的名称和绑定对象的关系。
  • 执行被调用的模块

注意:
1. 对一个模块,第二次重复导入时,不会再创建名称空间,因为已经存在了。因此,也不会有执行效果。
2. 导入模块的名称空间独立于当前脚本的名称空间,当前空间的变量和模块空间的变量即使重名,也互不影响。比如存在module.x = 10, 当前空间中也有一个全局变量x, 那无论怎样修改x的值,module.x的值都不会变。
3. 我们也可以通过from module import func1,func2/var/* 这种方式来导入模块的具体内容,这样,在调用模块中的方法时就不用通过module.func() , 而可以直接func() 但是这样有一个问题,重名的问题。看下面这个栗子:

x = 'from test'
from module import *    # 从module中导入所有对象。moduele中有一个全局变量 x = 'from module
print(x)    # 这时,打印出来的结果是 "from module"
from module import *    # 从module中导入所有对象。moduele中有一个全局变量 x = 'from module
x = 'from test'
print(x)    # 这时,打印出来的结果是 "from test"

从上面可以看出,哪个对象生效取决于调用顺序,就近原则。
因此,在导入模块时,推荐用import的方式。

if __name__ == ‘__main__’

当我们在当前脚本print(__name__) 时,结果永远是__main__, 而当这个脚本被调用时,__name__ 的值就是被调用脚本的脚本名(模块名)。所以,在脚本中的主函数执行前,加if __name__ == '__main__' 条件判断,有一个好处,我们可以直接执行这个函数,而当这个脚本(模块)被调用时,由于if条件不成立,函数就不会执行。

Package包

包的定义

包是组织模块的方式。在python中,包可以理解为一个文件夹,但是每个文件夹里必须有一个__init__.py 文件

调用方式

from package import module 同导入模块一样,package也必须在sys.path的路径列表中才行。
注意:当我们在脚本test.py中从一个包里导入一个自定义模块A,而该模块中又导入了另一个自定义模块B时,会报错。这是因为当前的sys.path路径中找不到模块B。解决方案是,在模块A中导入模块B时,用from package import module的形式。(这个package应该与test.py在一个目录层级下)

组织程序

可以按照包来组织,一个包只放主程序,而相关调用模块则放在其它同级的包里,效果如下:
这里写图片描述
说明:bin包里面只放启动文件 bin.py;core包里面放要调用的核心模块,main模块中写函数的主逻辑。

__init__.py

调用包时:执行__init__.py
通过init 导入下面层级的包,模块。提供给外部接口时,就可以直接import最上层的包名,点方法调用各个功能,而不用通过from pack1.pack2 这样层层找的方式。

模块调用的可迁移性

我们在自己终端写的程序,调用自定义模块时路径没有问题,那如何保证程序传播给另一个终端,仍然实现模块的正常调用呢。

import sys
import os

c_path = os.path.abspath(__file__)  # 获取当前脚本的绝对路径 (__file__的值时当前脚本的相对路径)
dir = os.path.basename(c_path) # 获取当前脚本的包目录
base_dir = os.path.basename(dir) # 获取包目录的上层目录base_dir(所有的包都组织在base_dir下)
sys.path.insert(0,base_dir) # 将base_dir加入sys.path, 这样在导入包下面的模块时,就都能找到了。
简化:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,BASE_DIR)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值