day5-Python模块及import本质

定义

模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能)本质就是.py结尾的python文件(文件名:test.py,模块名:test)

包(Package):用来从逻辑上组织模块的,本质就是一个目录(必须带有一个__init__.py文件)

导入方法

导入一个模块:import module_name

导入多个模块:import module1_name,module2_name

程序目录结构

#module_dick.py代码
name = "Jacky"
def say_hi():     #方法一
    print("hello world")

def logger():     #方法二
    print("in the module")

def run():        #方法三
    pass

#main.py代码
import module_dick  #导入一个模块

print(module_dick.name)
module_dick.say_hi()  #调用模块中方法

#输出
Jacky
hello world

解析:我们在main.py中导入import module_dick相当于此模块中的代码在main.py中执行了一遍,封装以后,并把结果赋给module_dick这个变量(即:module_dick = all_code),所以在main.py中调用module_dick模块中的方法时,需要在调用方法的前面加上module_dick模块名这个引子。

导入模块里所有方法:from module_name import *

#main.py代码
from module_dick import * #导入一个模块里面的所有方法

def logger():
     print("in the main")

print(name)  #直接调用,不需要module_dick.name进行调用
say_hi()     #直接调用

#输出
Jacky
hello world

解析:不建议使用此种导入方法,因为它不仅将def方法导入,还有变量等等,如name="Jacky"也都导入了。也就是说它把module_dick里所有的的代码都导入进来执行了一遍,如果当前main.py里面也有一个方法logger(),那么就不知道调用的是导入模块中的logger方法还是自己的logger方法。所以*要慎用。避免这种冲突的情况。

那么,出现这种情况可以通过下面方法来解决

导入特定方法:from module_name import X as Y

#main.py代码
from module_dick import logger as logger_dick  #将x使用别名y来代替

def logger():
    print("in the main")

logger()
logger_dick()

#输出
in the main
in the module

解析:在这里,为了区别main.py中的logger和module_dick中的logger方法,使用了别名来区分。

导入模块里多个方法:from module_name import m1,m2.m3

#main.py代码
from module_dick import logger,say_hi,name  #在一个模块里面导入多个方法或变量

def logger():
    print("in the main")
print(name) logger() say_hi() #输出
Jacky in the main hello world 

解析:在main.py中导入from module_dick import 特定方法相当于首先打开module_dick这个文件,然后找到特定的方法或变量,然后把特定的方法或变量拿到main.py处执行一遍,所以说在调用时,直接调用即可。

import本质(路径搜索和搜索路径)

1.import模块的本质

把python解释一遍,然后所有代码赋值给了module_name(这个变量)

1.1 import module_name:相当于所有代码赋值给了module_name(这个变量),使用module_name里面的方法或变量时,必须使用module_name.X进行调用
1.2 from module_name import X:相当于打开module_name这个文件只导入X这个变量,使用该X时直接调用即可

2.import包的本质

执行该包下面的__init__.py文件

2.1 import module_name ——>module_name.py——>module_name.py的路径(路径搜索)——>sys.path(搜索路径)
#main.py代码
import sys print(sys.path) #输出 ['/Users/huwei/PycharmProjects/s14/module_2/module', '/Users/huwei/PycharmProjects/s14', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages'] #列表的形式路径

解析:从sys.path输出来看,搜索路径是从当前目录下开始找,挨个个找,如果导入的模块路径在此列表中没有,那么就需要进行人工导入相应模块所在的目录(搜索路径)到此sys.path列表中供查找。

2.2 获取当前文件路径:os.path.asbpath(__file__)是一个列表,获取当前文件目录os.path.dirname(os.path.asbpath(__file__)),获取上一层文件目录os.path.dirname(os.path.dirname(os.path.asbpath(__file__)))
2.3 再将该文件目录追加到系统sys.path.append(XXX)或Insert(Y,XXX)
2.4 导入包package就是运行__init__.py文件(记住),那么,我们将模块导入到包就可以在使用时通过包进行调用:在__init__.py文件里使用相对导入:from . import module_name 模块
#test包下的__init__.py代码
from . import test1,test2,test3  #从当前目录(相对路径:代表__init__.py自己)导入模块test1,test2,test3

#test1代码
def man1():
    print("from test package test1")

#test2代码
def man2():
    print("from test package test2")

#test3代码
def man3():
    print("from test package test3")

#main.py代码
import test  #本质是执行__init__.py的文件

test.test1.man1()
test.test1.man2()
test.test1.man3()

#输出
from test package test1
from test package test2
from test package test3

导入优化

在两个函数中,每次调用module2_dick.test都需要事先进行一个导入module_test后再进行方法test的查找,那么我们如何改变这种情况呢?

#module2_dick.py代码
def test():
    print("in the module2_dick")

#main.py代码
import module2_dick

def logger():
        module2_dick.test()
        print("in the logger")

def search():
        module2_dick.test()
        print("in the search")

logger()
search()

#输出
in the module2_dick
in the logger
in the module2_dick
in the search

#优化导入的方法
from module2_dick import test

def logger():
        test()
        print("in the logger")

def search():
        test()
        print("in the search")

logger()
search()

#输出
in the module2_dick
in the logger
in the module2_dick
in the search

解析:使用from module import 导入相应的方法,相当于将方法拿到当前文件执行一遍,而不需要每次都重新检索一遍代码,使代码速度提升。

posted @ 2017-10-25 09:31  Mr.hu  阅读(254)  评论(0)    收藏  举报