模块,循环导入

模块的四种形式

在python中,总共有以下四种形式的模块:

  1. 内置模块:python解释器启动自带的模块,random / time ……
  2. pip install 安装的模块
  3. 自定义模块:如果你自己写一个py文件,在文件内写入一堆函数,则它被称为自定义模块,即使用python编写的.py文件
  4. 包:把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称为包)

import和from...import...

import 模块

import time这个代码做了以下事情

  • 开辟内存空间,内存空间命名为time
  • 把time.py中的所有代码读入名称空间,然后运行
  • 通过time.方法名使用time模块中的方法

from 模块 import 方法

from time import sleep

  • 开辟内存空间,内存空间命名为time
  • 把time.py中的所有代码读入名称空间,然后运行
  • 把sleep()方法读入当前文件中,因此可以直接使用sleep方法

如果想使用多个方法:

from time import sleep,time

导入所有功能:

from time import *

import与from...import的优缺点

import:

  • 优点:永不冲突
  • 缺点:每次导入多输入几个字符

from...import的优缺点:

  • 优点:少输入几个字符
  • 缺点:容易与当前执行文件中名称空间中的名字冲突

循环导入

# m1.py
from m2 import y

x = 10
print('m1:', x, y)
  1. 创建m2的名称空间
  2. 执行m2.py,将执行产生的名字丢到m2.py
  3. 在当前执行文件中拿到m2.x
# m2.py
from m1 import x

x = 20
print('m2:', x, y)
  1. 创建m1的名称空间
  2. 执行m1.py,将执行产生的名字丢到m1.py
  3. 在当前执行文件中拿到m1.y

由于模块永远只会开辟一次空间,所有这样不会永远循环下去,一次就会报错

解决方法

方案一:

# m1.py
x = 10
from m2 import y
print('m1:', x, y)
# m2.py
y = 20
from m1 import x
print('m2:', x, y)

方案二:

这个解决方法就是:函数定义阶段只检测语法,不执行代码

# m1.py
x = 10
def f1():
    from m2 import y
    
    print('m1:', x, y)
    
f1()
# m2.py
y = 10
def f2():
    from m2 import x
    
    print('m2:', x, y)
    
f2()

注:模块永远只开辟一次;from m1 import 必须执行m1.py中所有代码

模块的搜索路径

模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径(某个文件夹)。如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。

模块的搜索路径指的就是在导入模块时需要检索的文件夹。

导入模块时查找模块的顺序是:

  1. 先从内存中已经导入的模块中寻找
  2. 内置(环境变量)
  3. 自定义模块

python文件的两种用途

python文件总共有两种用途,一种是执行文件;另一种是被当做模块导入。

编写好的一个python文件可以有两种用途:

  1. 执行文件,一个文件就是整个程序,用来被执行
  2. 模块,文件中存放着一堆功能,用来被导入使用
# test123.py

def f1():
    print('from f1')
    
f1()
# run.py

from test123 import f1
如果直接运行run.py会直接运行test123.py中的f1(),但是如果我们在test123.py中加上if`__name__=='__main__'这句话,则可以防止运行run.py时执行f1()。

__name__=='__main__'不成立,__name__!='__main__'

当test123为模块文件时,__name__等于文件名

原文地址:https://www.cnblogs.com/setcreed/p/11605004.html