Python模块详解

模块介绍

什么是模块

定义:逻辑上来说模块就是一组功能的组合;实质上一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。

import加载的模块分为四个通用类别:

  1. 使用python编写的代码(.py文件);
  2. 已被编译为共享库或DLL的C或C++扩展;
  3. 包好一组模块的包
  4. 使用C编写并链接到python解释器的内置模块;
  • 模块(module)其实就是py文件,里面定义了一些函数、类、变量等
  • 包(package)是多个模块的聚合体形成的文件夹,里面可以是多个py文件,也可以嵌套文件夹
  • 库是参考其他编程语言的说法,是指完成一定功能的代码集合,在python中的形式就是模块和包

模块的导入

想要使用模块,必须先要将模块加载进来,可以通过关键字 import 或 from进行加载;需要注意的是模块和当前文件在不同的命名空间中。

模块的构成

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

模块导入的过程

  1. 找到这个需导入的模块;

  2. 判断这个模块是否被导入过;

  • 如果没有被导入过:
    创建一个属于这个模块的命名空间;如果用户没有定义变量来引用这个模块的内存地址的话,那么就使用模块的名称来引用这个模块的内存地址;如果用户使用as来指定变量接受这个内存地址的话,那么就将内存地址赋值给这个变量;且下文在调用时只能使用这个变量进行调用不能再使用模块名进行调用了。然后执行这个模块中的代码;

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

关于导入的模块与当前空间的关系

带入的模块会重新开辟一块独立的名称空间,定义在这个模块中的函数把这个模块的命名空间当做全局命名空间,这样的话当前的空间就和模块运行的空间分隔了,谁也不影响谁;

为模块起别名

  • 模块在导入的时候开辟了新空间内存,默认是使用模块的名称来引用这个内存地址的,有时候模块的名称很长再加上执行调用里面的功能的时候,就显的很不方便,为了更好的使用模块,我们可以给模块起别名;

  • 也就是在导入模块的时候我们不让它使用默认的名字来引用内存地址,而是由我们自己定义的变量来引用这个模块的内存地址;

方法:import my_module as mk

  • 这样的话就表示使用变量mk来引用这个内存地址,然后我们在文中再使用这个模块的时候,只要使用mk来调用这个模块里的功能即可。

  • 还有一种好处是当有两个模块需要根据用户的输入来选择使用的话,那么,用自定义变量来引用内存地址就再好不过了

参考链接 python模块详解

import运行本质

执行导入模块命令时,会首先检查待导入的模块是否在当前已有模块之中,如果有则跳过import。因此模块之间相互引用不会导致无限循环。

查看当前已导入模块使用下面方法

import sys
sys.modules
#得到结果是一个字典,键是模块名,值是文件所在路径

在这里插入图片描述

import语句与文件执行

在这样的文件结构下

trymodule
│   first.py
├───folder1
│   │   abcd.py
│   │   __init__.py
folder1是一个package,abcd是一个module

import folder1 只是导入package,相当于执行__init__.py文件
from folder import abcd则执行了__init__.py文件文件与abcd.py文件
from folder1.abcd import b其实也执行了__init__.py文件文件与abcd.py文件

if __name__ == '__main__'

在这里插入图片描述

自定义模块

定义一个calculate.py文件

__all__ = ['add', 'number']  #    #1
import sys
number = 100
name = 'name'

def add(*args):
    if len(args) > 1:
        sum = 0
        for i in args:
            sum += i
        return sum
    else:
        print('至少传入两个参数')
        return 0


def minus(*args):
    if len(args) > 1:
        m = 0
        for i in args:
            m -= i
        return m
    else:
        print('至少传入两个参数')
        return 0
  1. 定义其他文件可以调用的内容,import * 代表导入all中所有的内容,不在all里的则不会被导入
class Calculate:
    def __init__(self, num):
        self.num = num

    def test(self):
        print('正在运算')

    @classmethod
    def test1(cls):
        print('calculate中的类方法')

def test():
    print('我是测试')

print('__name__:', __name__)           
print(sys.argv)

if __name__ == '__main__':             #1

    test()

在这里插入图片描述

  1. __name__在calculate.py文件中的输出结果是__main__,但是在其他文件中执行的结果是calculate
  2. 在导入模块的时候python解释器会把模块中的代码加载到内存,如果模块中有可执行的代码,比如print,也会默认执行,这样可以通过__name__来避免模块中的文件被执行

在test.py文件中导入calculate

import calculate
import sys

list1 = [1, 2, 3, 4]
result = calculate.add(*list1)
print(result)
print(calculate.number)
calculate.Calculate.test1()
print(sys.argv)

在这里插入图片描述

import会加载模块里的代码到内存,如果模块中存在函数调用,也会执行该调用

在这里插入图片描述

包的导入

包的几种导入方式

from folder1 import abcd
import folder1
from folder1.abcd import b
import folder1.abcd
  • 只是导入包不能随便使用其中的模块,要导入到具体模块或者变量的层次
  • 文件夹与文件之间可以用.也可以用from import格式,而文件与里面的变量之间只能用from import格式,即不能import folder1.abcd.b

__init__.py文件

__init__.py文件其实是一个特殊的文件,它相当于名为folder1模块,即如果使用import folder1则可以调用在__init__.py文件文件中定义的变量。

导入模块的搜索路径

用import hello时,python会搜寻hello.py文件,搜索顺序如下

  • 首先搜寻内置模块是否有hello(所以我们定义的模块名不要和内置模块相同)
  • 如果内置模块没有,则看下面这些目录里有没有
sys.path

在这里插入图片描述

其中第一个表示当前的工作路径,我们可以看出安装的第三方包所在路径(‘C:\Program Files\Anaconda3\lib\site-packages’)也在这个列表之中,所以无论工作路径在哪里,都能搜寻到这些包。

绝对引用与相对引用

python中的import分为绝对引用和相对引用两种。它们之间的差异在于,引用模块时 定位被引用模块位置 的方式不同

  • 绝对引用是通过.的连接,指定出最高级文件(夹),到目标文件的绝对路径。我们上面的所有用法都属于绝对引用。
  • 而相对引用是 指定待引用模块与当前文件的相对位置,.表示上一级文件
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值