import in python

import做了什么
  1. sys.modules中寻找该模块是否之前被引入过,如果有,引入该名字[import mode相当于mod = sys.modules['mod']]
  2. 如果没有:
    1. sys.path中寻找该模块,如果没找到,报错
    2. 如果找到,创建一个空的模块对象,通常为dict()
    3. 将该模块写入sys.modules
    4. 加载该模块文件(如果有必要,先编译)
    5. 执行该模块代码,defimportclass实际上都是表达式,执行之后才可以被访问
形式
from mod import *
'''
for all public_name in mod:
    sys.modules[public_name] = public_name的定义
'''

备注:

  • 只能出现在模块作用域
  • mod本身没有被引入,因此mod.name会报错
  • 会寻找该模块定义的公共名字(public names),如果有__all__的定义,那么该变量定义的名字均为公共的,否则该模块中不以_开头的名字将被视为公共名字
import X
'''
sys.modules['X'] = X的定义
'''

备注:

  • 只能引入包或模块,不能引入模块内定义的类、函数或变量
  • 如果X是包,会执行init.py,如果里面有import,则会在sys.modules加入引入的模块
from mod import foo
'''
foo 可以为包、模块、类、函数、变量
submodules['mod'] = mod的定义
submodules['mod.foo'] = mod.foo的定义
'''
最佳实践
  • 不要使用from module import *
  • 在文件的开始处import所需的模块
  • 以下列顺序import不同的模块:
    1. 系统库的模块,如ossys等;
    2. 第三方的模块
    3. 当前工程自定义的模块
  • 不使用相对路径的import,永远使用绝对路径import 参考PEP328
  • 可以在函数内import,比如平台相关的代码,或者降低模块初始化的耗时
  • 如果某个类的对象需要使用某个模块,可以在__init__(self)import该模块并且赋值为该类对象的一个成员变量,这样该模块在对象整个生命周期都是可用的,但一定要写在函数内,如果没有,那么实际上该模块的初始化是发生在该类所属模块的初始化阶段;
PEP328
  • 永远使用绝对路径import,让所有的模块都从sys.path中寻找,避免出现语义混淆:
    • import item:不清楚是相对于当前模块的其他模块,还是某个package
  • 如果从一个模块或包中引入很多名字,那么使用()括起来:
    from package import (m1, m2, m3
    m4, m5, m6)
    
  • 如果使用相对引用,那么只能使用from <> import mod,如果使用import mod,那么被认为是绝对引用
例子
# 文件结构:
package/
    __init__.py
    subpackage1/
        __init__.py
        moduleX.py
        moduleY.py
    subpackage2/
        __init__.py
        moduleZ.py
    moduleA.py
    main.py
访问包的模块
# main.py
'''
如果package目录下的__init__.py中没有import moduleA,
下面这个语句会报错: 'module' object has no attribute 'moduleA'
原因是默认不会import一个包所包含的模块
'''
import package
print package.moduleA.foo

'''
推荐写法如下
'''
import package.moduleA as modA
print modA.foo

# 或
from package import moduleA
print moduleA.foo
相对路径引用

同一package的module相互引用

# moduleX.py
from . import moduleY
from .moduleY import spam as ham
from ..subpackage1 import moduleY

引用不同package的module

# moduleX.py
from ..subpackage2 import moduleZ
from ..moduleA import foo
from ...package import bar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值