爱生活,乐分享,大家好才是真的好!
返回顶部

【大数据课堂0003】【import】__file__ 作用以及模块导入方法

【原理】import 导入模块,就是能够根据sys.path环境变量的值,找到具体模块的路径。

import上一级目录的模块===>  

sys.path.insert(0,'../') #最简洁做法

python 执行py 文件的时候,默认就会把当前目录增加到sys.path中。sys.path[0]。

– src 
  |– mod1.py 
  |– test1.py

test1.py中导入模块mod1, 则直接使用
import mod1 或 from mod1 import *
– src 
|– mod1.py 
|– mod2 
  | – mod2.py 
– test1.py

from mod2.mod2 import * 或 import mod2.mod2.
– src 
  |– mod1.py 
  |– mod2 
   |– mod2.py 
  |– sub 
    | – test2.py 
  – test1.py 

#test2.py 调用模块
import sys 
sys.path.insert(0,'../')# 简洁 ..==../
#parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#
sys.path.insert(0,parentdir)
import mod1
import mod2.mod2

 

python中,import module会去sys.path搜索,sys.path是个列表,并且我们可以动态修改。

要import某个目录的module,我们sys.path.insert(0,somedir)来加入搜索路径,就可以import了。
既然这样,要import上一级目录的module,可以sys.path.insert(0,parentdir)。
不过这种写绝对路径的方式,如果文件放到其它地方,就不行了。 
所以用动态方法来获取上一级目录。当前文件执行的目录的路径就加入到python 路径里面,后面不管你目录移动到什么位置,里面的文件都能执行。

__file__:当前执行的文件,不带路径,除非自己带路径。Python a.py __file__==a.py ; python D:/b.py __file__==D:/b.py
import os,sys 
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
sys.path.insert(0,parentdir)

为什么用sys.path.insert(0,parentdir) 而不是用sys.path.append(parentdir)呢
因为是遍历搜索路径的,所以如果在其它路径里也有个同名的module,会import错。用sys.path.insert(0,parentdir)可以确保先搜索这个路径;2,自定义的优先级要高,保证优先搜到。

 

 

解决循环import的问题: A中导入B ,B 也需要A中内容。----理顺逻辑,组织代码

# 不能逻辑不清晰,循环死调用,a里调b b里有调a

在python中常常会遇到循环import即circular import的问题。
现实中经常出现这种滑稽的情况,
安装无线网卡的时候,需要上网下载网卡驱动..

这样就产生了循环import的问题。
解决循环import的方法主要有几种。
1.延迟导入(lazy import)
即把import语句写在方法或函数里面,将它的作用域限制在局部。
这种方法的缺点就是会有性能问题。
2.将from xxx import yyy改成import xxx;xxx.yyy来访问的形式
3.组织代码
出现循环import的问题往往意味着代码的布局有问题。
可以合并或者分离竞争资源。
合并的话就是都写到一个文件里面去。
分离的话就是把需要import的资源提取到一个第三方文件去。
总之就是将循环变成单向。

 

“  /    ”:表示根目录,在windows系统下表示某个盘的根目录,如“D:\”;

“  ./   ”:表示当前目录;(表示当前目录时,也可以去掉“./”,直接写文件名或者下级目录)

“  ../  ”:表示上级目录。

 

原理:

  原来在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。当你将一个包作为模块导入(比如从 xml导入 dom )的时候,实际上导入了它的 __init__.py 文件。

  一个包是一个带有特殊文件 __init__.py 的目录。__init__.py 文件定义了包的属性和方法。其实它可以什么也不定义;可以只是一个空文件,但是必须存在。如果 __init__.py 不存在,这个目录就仅仅是一个目录,而不是一个包,它就不能被导入或者包含其它的模块和嵌套包。

_init__.py 文件:

__init__.py 控制着包的导入行为。假如 __init__.py 为空,那么仅仅导入包是什么都做不了的。

__init__.py 中还有一个重要的变量,叫做 __all__。我们有时会使出一招“全部导入”,也就是这样:

from PackageName import *

这时 import 就会把注册在包 __init__.py 文件中 __all__ 列表中的子模块和子包导入到当前作用域中来。比如:

#文件 __init__.py
__all__ = ["Module1", "Module2", "subPackage1", "subPackage2"]

__init__.py 文件会在导入时被执行。

posted @ 2019-07-23 17:02  博观约取&厚积薄发  阅读(563)  评论(0编辑  收藏  举报
回到顶部
返回顶部