python import重点

模块的搜索路径

  1. 程序主目录
  2. PYTHONPATH目录,如果已经进行了设置
  3. 标准链接库目录
  4. 任何.pth文件的内容(if exsited)

这四个组建组合起来就变成了sys.path

模块会在第一次import或from时载入并执行,==并且只会在第一次如此==。这是因为载入模块的时候开销比较大。

import和from与def一样,都是可执行语句,而不是编译期间的生命,他们可以嵌套在if测试中,出现在def中,直到执行程序时,python执行到这行语句,才会进行解析。他们都是隐性的赋值语句。

import是赋值整个模块,from是把赋值给本地的变量名称,这两点是有不同的。

from module import name1 , name2    #copy these two names out

this same as 
import module 
name1 = module.name1
name2 = module.name2
del module

这并不意味着from只会加载模块的一部分,它仍然会把整个模块导入到内存中。

关于reload

  • reload会再模块当前命名空间内执行模块文件的新代码。重新执行模块文件的代码会覆盖其现有的命名空间,并非进行删除而进行重建;
  • 文件中顶层赋值语句会使得变量换新值;
  • 常在会影响所有 ==使用== import读取了模块的客户端;
  • 重载只会对==以后== 使用from的客户端造成影响。==之前使用== from来读取属性的客户端并不会受到重载的影响,那些客户端引用的依然是重载前所取出的旧对象。==因为form是复制!==

模块包

除了模块名之外,导入也可以指定目录路径,python代码的目录就称为包,因此,这类导入就称为包导入。


包导入不能够出现绝对路径,如import c:xxx\xxx\xxx,可以把路径放入到PYTHONPATH或者.pth文件中。

_ init _ .py必须存在路径中的每个目录里面,否则导入包会失败。住目录里面可以没有这个文件,或者PYTHONPATH的路径中。

为什么会需要这个东西呢,可以想一下,假如有相同的名称的目录隐藏在模块的搜索路径中咋办?所以这个文件可以防止这种情况的出现,此外它的作用更表现在其他方面:

  • 包初始化,python首次导入某个目录时,会自动执行该目录下的_ init _ .py文件中所有程序代码。所以这类文件是放置包内文件所需要初始化的代码的场所。
  • 模块命名空间的初始化。这个命名空间包含了_ init _ .py赋值的所有顶层变量名,和里面的模块名。
  • from*语句的行为,可以在init.py里面使用all列表来定义目录语句不会自动加载嵌套于该目录内的子模块。只会加载该目录init.py文件中的赋值语句定义的变量名,包括该文件中程序代码明确导入的任何子模块。

实际上,路径中每个目录名称都会变成赋值了模块对象的变量,而模块对象的命名空间则由该目录内的init.py文件中所有赋值语句进行初始化的。

在python3.0中,在包中运行导入都是绝对路径了。如果要从包中导入一个模块,而没有给出从包根目录的完整路径,在from语句中使用点语法可以做到相对导入。

from . import string #从当前包模块里面导入

在当前工作目录下面不允许使用相对导入,在python3.0中包内导入必须是相对导入,不然会出错或者直接按照sys.path路径去寻找模块(是包含当前工作目录的)。并且在使用相对导入时候,模块必须存在于本地,如果不存在包中,如果存在系统中但是不在包中仍然会出错。

from* 小技巧

这些只是针对from * 的

  • from* 会把所有变量名赋值出去,导入者可能得到超出它所需要的部分。那么使用_X 可以对from* 屏蔽这个变量。注意是对from* 屏蔽,如果使用import还是可以把这个变量找出来。
  • 也可以在模块顶层把可以提供的变量名赋值给 _ all_ ,eg
    _ all_ = [‘error’, ‘abc’]。python会先找 _ all_列表;如果没有定义的话from* 会寻找没有单下划线的所有变量。

修改模块搜索路径

import sys
sys.path.append(r'c\xx')

一旦修改所有的导入和文件都共享了同一个sys.path,并且这个sys.path是可以随意修改的,但是sys.path只会修改当前进程,如果进程结束是不会保留的

顶层代码的语句次序的重要性

当模块首次导入(重载时),python会从头到尾执行语句。
- 在导入时,模块文件顶层的程序代码(不在函数内)一旦python运行到时,就会立刻执行。因此,该语句是无法引用文件后面位置赋值的变量名。
- 位于函数主体内的代码知道函数被调用时才会运行。因为函数内的变量名在函数实际执行前都不会解析,通常可以引用文件内任意地方的变量。

func1()    #error  func1() not yet assigned 
def func1():
    print(func2())    # ok
func1()               # error     

def func2():
    return 'hello'

func1()       # ok
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值