Python中互相import注意事项

1.示例代码

1).循环引用中的模块不能在定义阶段就直接调用,将引用的模块的代码放在当前py文件的函数和类方法中

#module1.py

from import_demo import module2
class Model(object):
    def __init__(self):
        self.name = "aaa"
    def do_something(self):
        module2.printName()

m = Model()

#module2.py

from import_demo import module1
name = "module2"

def print_model(model):
    print(module1.Model.name)

def printName():
    print(name)

2).将调用的代码放在if __name__ == '__main__':中,程序运行的时候执行调用如下:
#module1.py

from import_demo import module2
class Model(object):
    def __init__(self):
        self.name = "aaa"
    def do_something(self):
        module2.printName()

m = Model()

if __name__ == '__main__':
    m.do_something()

执行结果

 3.错误方式:不放在if __name__ == '__main__': 中直接引用另一个模块属性或者方法:

from import_demo import module2
class Model(object):
    def __init__(self):
        self.name = "aaa"
    def do_something(self):
        module2.printName()

m = Model()
m.do_something()

执行执行报错如下:

2.Import核心原理描述

1.标准import

Python中所有加载到内存的模块都放在 sys.modules

当 import 一个模块时首先会在这个列表中查找是否已经加载了此模块

如果加载了则只是将模块的名字加入到正在调用 import 的模块的 Local 名字空间中

如果没有加载则从 sys.path 目录中按照模块名称查找模块文件,模块可以是py、pyc、pyd,找到后将模块载入内存,并加到 sys.modules 中,并将名称导入到当前的 Local 名字空间。

一个模块不会重复载入

多个不同的模块都可以用 import 引入同一个模块到自己的 Local 名字空间,其实背后的 PyModuleObject 对象只有一个

一个容易忽略的问题:import 只能导入模块,不能导入模块中的对象(类、函数、变量等)

例如:模块 A(A.py)中有个函数 getName,另一个模块不能通过 import A.getName 将 getName导入到本模块,只能用 from A import getName

2.嵌套import

1)顺序嵌套

例如:本模块导入 A 模块(import A),A 中又 import B,B 模块又可以 import 其他模块…
本模块 import A 之后本模块只能访问模块 A,不能访问模块 B 及其他模块

2)循环嵌套
例如上例

Python 内部导入一个模块module2会分成几个步骤:
(1)在 sys.modules 中查找符号 “module2
(2)如果符号 module2 存在,则获得符号 module2 对应的 module 对象。
  从 <modult B> 的 __dict__ 中获得符号 “do_something” 对应的对象,如果 “do_something” 不存在,则抛出异常。
(3)如果符号 B 不存在,则创建一个新的 module 对象 <module B>,注意,此时,module 对象的 __dict__ 为空。
执行 module2.py 中的表达式,填充 <module module2> 的 __dict__。
从  <module module2> 的 __dict__ 中获得 “do_something” 对应的对象,如果 “do_something” 不存在,则抛出异常。

其他循环嵌套的导入逻辑类似

3. 包 import
    只要一个文件夹下面有个 __init__.py 文件,那么这个文件夹就可以看做是一个包。包导入的过程和模块的基本一致,只是导入包的时候会执行此包目录下的 __init__.py 而不是模块里面的语句了。另外,如果只是单纯的导入包,而包的 __init__.py 中又没有明确的其他初始化操作,那么此包下面的模块是不会自动导入的。

参考文献:https://www.jb51.net/article/51815.htm

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值