pyhton之路---模块篇

模块循环导入问题 

 在一个文件夹内建立三个.py文件,m1.py 和 m2.py 和 run.py,前两者作为被导入模块,run.py为执行文件 

#执行文件内容
import  m1


#m1模块内容
print('正在导入m1...')
from m2 import y
x = 1

#m2模块内容
print('正在导入m2...')
from m1 import x
y = 2

#运行run,结果:
正在导入m1...
正在导入m2...
ImportError: cannot import name 'y'

 过程分析:

  1首先要明确的是:谁是执行文件,谁是被导入模块

  2.首次导入模块发生的三件事

 执行run.py时,申请了run.py的名称空间,首次导入m1时,申请m1这个被导入模块的名称空间,开始执行m1模块内的代码,执行到from m2 import y时开始申请m2的名称空间,执行m2的模块体代码,再执行到from m1 import x 时,此时内存中已经存在m1的名称空间(虽然m1才执行到from m2 import y这里),python就直接去m1模块的名称空间中去寻找x,并试图在自己的名称空间内用一个变量名x指向m1中x的内存地址,但是此时的m1中还未存在x与1这个值的绑定关系

解决方法:

1.导入模块语句放在名字定义之后

#执行文件内容
import  m1
print(m1.y)


#m1模块内容
print('正在导入m1...')
x = 1
from m2 import y

#m2模块内容
print('正在导入m2...')
y = 2
from m1 import x

#运行run,结果:
正在导入m1...
正在导入m2...
2

2:导入模块就是为了使用的,如果是在函数内使用被导入模块,完全可以将导入语句放在函数内

#执行文件内容
import  m1
m1.f1()


#m1模块内容
print('正在导入m1...')
def f1():
    from m2 import y,f2
    print('m1.f1--->y',y)
    f2()
x=1

#m2模块内容
print('正在导入m2...')
def f2():
    from m1 import x
    print('m2.f2--->x',x)
y = 'm2'

#运行run,结果:
正在导入m1...
正在导入m2...
m1.f1--->y m2
m2.f2--->x m1

这是利用了,函数在定义阶段只检测语法,而不执行代码的原理

模块的搜索路径原则:内存中已经加载过的---->内置----->sys.path(注意:sys.path的第一个路径为执行文件的所在当前文件夹)

值得注意的是:所有被导入模块的搜素路径都是以执行文件的sys.path为准

例如我们在建立dir0文件夹,在其内建立dir文件夹以及与其同一级的run.py执行文件,在dir文件夹下建立两个同一级别的m1.py,m2.py

#这些文件run.py的内容
from dir import m3

#m1模块的内容
def f1():
    print('m1.f1')

#m2模块的内容
import m1
m1.f1()
#运行结果
ModuleNotFoundError: No module named 'm1'

当我们将import m1 改为from dir import m1就正确了

 

模块的绝对导入和相对导入:

绝对导入:以执行文件的sys.path为起点导入

       优点:执行文件和被导入模块都可以使用       缺点:导入麻烦

相对导入:参照当前所在文件的文件夹为起点查找  

用法:一个点代表当前文件夹,点点代表上一级,点点点代表上一级的上一级

所以:上个模块搜索路径的例子,  m3模块中的代码可以改写为:

from .m1 import f1
f1()
 

  

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值