37-模块

作者: ju7ran | 来源:发表于2019-04-20 13:39 被阅读2次

    模块与包

    在Python中,一个.py文件就是一个模块,模块是比类更高一级的封装。在其他语言,被导入的模块也通常称为库。

    模块可以分为自定义模块、内置模块和第三方模块。自定义模块就是你自己编写的模块,如果你自认水平很高,也可以申请成为Python内置的标准模块之一!如果你在网上发布自己的模块并允许他人使用,那么就变成了第三方模块。

    使用模块有什么好处?

    1. 首先,提高了代码的可维护性。
    2. 其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他的模块引用。不要重复造轮子,我们简简单单地使用已经有的模块就好了。
    3. 使用模块还可以避免类名、函数名和变量名发生冲突。相同名字的类、函数和变量完全可以分别存在不同的模块中。但是也要注意尽量不要与内置函数名(类名)冲突。

    为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package),包是模块的集合,比模块又高一级的封装

    包名通常为全部小写,避免使用下划线

    要在我们的程序中,使用其它的模块(包、类、函数),就必须先导入对应的模块(包、类、函数)。在Python中,模块(包、类、函数)的导入方式有以下四种:

    import xx.py
    from xx.py import xx
    from xx.py import xx,yy
    from xx.py import *
    from xx.py import xx as rename
    

    import xx.xx

    这会将对象(这里的对象指的是包、模块、类或者函数,下同)中的所有内容导入。如果该对象是个模块,那么调用对象内的类、函数或变量时,需要以module.xxx的方式。
    比如,被导入的模块Module_a:
    Module_a.py
    def func():
        print("this is module A!") 
    ----------------------------------------
    在Main.py中导入Module_a:
    Main.py
    import module_a
    module_a.func()  # 调用方法
    

    这个时候会新生成一个文件,xxx.cpython-36.cpy,这是Python解释器,在导入模块的时候,把导入的模块生成一个缓存文件。下次再来调用这个模块的时候直接来运行这个文件。cpython是c语言写的Python解释器。

    from xx.xx import xx.xx

    从某个对象内导入某个指定的部分到当前命名空间中,不会将整个对象导入。这种方式可以节省写长串导入路径的代码,但要小心名字冲突。
    在Main.py中导入Module_a:
    Main.py
    from module_a import func
    module_a.func()   # 错误的调用方式
    func()           # 这时需要直接调用func
    

    from xx.xx import *

    将对象内的所有内容全部导入。非常容易发生命名冲突,请慎用!
    from module_a import *
    def func():
        print("this is main module!")
    func()  # 从module导入的func被main的func覆盖了
    执行结果:this is main module!
    

    from xx.xx import xx as rename

    为了避免命名冲突,在导入的时候,可以给导入的对象重命名
    from module_a import func as f
    def func(): ## main模块内部已经有了func函数
        print("this is main module!")
    func()
    f()
    

    __name__

    如果我们是直接执行某个.py文件的时候,该文件中那么__name__ == __main__是True,但是我们如果从另外一个.py文件通过import导入该文件的时候,这时__name__的值就是我们这个py文件的名字而不是__main__

    这个功能还有一个用处:调试代码的时候,在if __name__ == __main__中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!

    test.py
    def test1():
        print("--1--")
    def test2():
        print("--2--")
    
    # test1()
    # test2()
    print(__name__)
    if __name__ == '__main__':
        test1()
        test2()
    
    ---------------------------------------
    main.py
    import test
    
    test.test1()
    test.test2()
    
    

    模块搜索路径

    不管你在程序中执行了多少次import,一个模块只会被导入一次。这样可以防止一遍又一遍地导入模块,节省内存和计算资源。那么,当使用import语句的时候,Python解释器是怎样找到对应的文件的呢?

    Python根据sys.path的设置,按顺序搜索模块。

    import sys
    sys.path
    ['', 'C:\\Python36\\Lib\\idlelib', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36', 'C:\\Python36\\lib\\site-packages']
    当然,这个设置是可以修改的,就像windows系统环境变量中的path一样,可以自定义。 通过sys.path.append('路径')的方法为sys.path路径列表添加你想要的路径。
    import sys
    import os
    new_path = os.path.abspath('../')
    sys.path.append(new_path)
    默认情况下,模块的搜索顺序是这样的:
    1.当前执行脚本所在目录
    2.Python的安装目录
    3.Python安装目录里的site-packages目录
    其实就是“自定义”——>“内置”——>“第三方”模块的查找顺序。任何一步查找到了,就会忽略后面的路径,所以模块的放置位置是有区别的。
    

    相关文章

      网友评论

        本文标题:37-模块

        本文链接:https://www.haomeiwen.com/subject/cinkgqtx.html