Python 模块和包

164 阅读3分钟

什么是模块?

模块是一系列功能的集合体。分为三类:内置模块、第三方模块、自定义模块。

模块有四种形式

  • 使用Python编写的 .py 文件
  • 已经被编译为共享库或 DLLCC++ 扩展
  • 把一系列模块组织到一起的文件夹。文件夹下需要有一个 __init__.py 文件
  • 使用 C 编写并链接到 Python 解释器的内置模块

为何要用模块

  • 内置与第三方的模块拿来就用,无需定义,这种拿来主义,可以极大地提升开发效率。
  • 自定义模块 可以将程序的各部分功能提取出来,放到一个模块中,供大家共享和使用。好处是可以减少代码冗余,程序组织结构更加清晰。

模块的使用

# pkg.py
print("你好,我是模块")

x = 1
def get():
    print(x)

def change():
    global x
    x = 0
# run.py
import pkg # 你好,我是模块

print(pkg.x) # 1
x = "m"
pkg.get() # pkg.py 中的 1

首次导入模块:

  1. 产生 pkg.py 的名称空间,将 pkg.py 运行过程中产生的名字放在 pkg 的名称空间中。
  2. 执行 pkg.py
  3. 在当前文件中产生一个名字 pkg,该名字指向 2 中产生的名称空间

注意:

  1. 模块名、名字,是 模块名.名称 的格式获取的,要指名道姓地问某一个模块要名字对应的值,不会与当前文件中的名称相冲突。
  2. 无论是查看还是修改,都是以原模块为基准的,和调用的位置无关。
  3. 不建议在一行同时导入多个模块
import pandas, numpy # 符合语法,但是不建议
  1. 模块习惯的导入顺序 python 内置的模块 => 第三方模块 => 本项目中自定义的模块
import time
import sys

import numpy
import pandas

import customized1
import customized2
  1. 模块的别名
import 包名 as 别名
  1. 模块是第一类对象
  2. 自定义模块的命名应该采用纯小写 + 下划线的风格
  3. 可以在函数中导入
def func():
    import foo

Python文件的用途

一个Python文件可以被当作文件运行,也可以被当作模块导入。 image.png

Python内置了 __name__ 变量

  • 当该 Python 文件被运行时,__name__ 的值是 __main__
  • 当该 Python 文件被当做模块导入时,__name__ 的值是模块名字;
  • Pycharm 中的快捷键:main => if __name__ == "__main__":
if __name__ == "__main__":
    # 本文件作为主文件时
    get()
    change()
else:
    # 当本文件被当作模块导入时
    pass

以上案例在线测试: replit.com/@Vooce/pkg1

from ... import ... 导入模块

上面我们介绍了如果用 import 导入模块,这种方式需要以前缀.模块的方式来使用导入的函数和变量。优点是肯定不会与当前名称空间中的名字冲突,但是加了前缀会显得比较麻烦。怎么能在使用的时候简化呢?下面我们来介绍另一种导入方式:from ... import ...

# run.py
from pkg import x
from pkg import get

from pkg import * # 导入全部
__all__ = ["x", "get"] # __all__ 可以用来控制*代表的名字有哪些

导入模块时:

  1. 产生 pkg.py 的名称空间,将 pkg.py 运行过程中产生的名字放在 pkg 的名称空间中。
  2. 执行 pkg.py
  3. 在当前的名称空间拿到名字,把该名字指向(在导入时)模块中对应的内存地址。
  • 优点: 代码更精简
  • 缺点: 容易与当前的名称空间混淆

image.png

循环/嵌套导入的异常

# m1.py
from m2 import y
print("导入m1")

x = "m1"
# m2.py
from m1 import x
print("导入m2")

y = "m2"
# main.py
import m1,m2

=> 返回的结果

ImportError: cannot import name 'x' from partially initialized module 'm1' 

解决的方法

def f1():
    from m1 import x