• python的模块


    前言

    在开发过程中,为了编写可维护的代码,我们会将很多函数进行分组,放到不同的文件中去。这样每个包的代码相对来说就会减少,也利于后期的维护和重复的使用。很多编程语言都采用这样的组织代码方式,在python中,一个'.py'文件就被称为是一个模块。很多时候我们我们编写代码也不用从头开始编写,因为当一个模块编写完毕,就可以别其他地方引用,我们在编写程序的时候经常引用其他的模块。

    常见的模块又分为三种:

    • python标准库,就是python为我们提供的经常使用的模块
    • 第三方模块
    • 自定义模块

    包的使用

    如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。

    举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。

    现在,假设我们的abcxyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块。这个包就相当于是创建了一个文件夹。引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。

    请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录(文件夹),而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是对应包的名字。

    调用包就是执行包下的'__init__.py'文件。

    模块的导入

    关于模块导入,我们要先了解一些事情:

    1. 当我们运行一段程序,都会有一个启动的文件。
    2. 当我们导入一个模块的时候,python解释器寻找对于文件的时候会有自己的搜索路径顺序,这个顺序在sys.path中存放着。
    3. 当我们引入一个文件的时候,它会先执行这个文件中的内容。如果想看看的话,不妨自定义一个模块,然后在里面放入print语句,再调用这个模块看看效果。
    4. 如果我们引入的模块中有和当前模块中同名的函数,引入的模块就会被屏蔽。

    import语句

    import用于导入和启动文件同目录下的模块

    格式:

    import module1[, module2[,... moduleN]

    from..import语句

    这个语句是引用和启动文件同目录下的包中的模块

    格式:

    from modname import name1[, name2[, ... nameN]]

    这个声明不会把整个modulename模块导入到当前的命名空间中,只会将它里面的name1或name2单个引入到执行这个声明的模块的全局符号表。

    还有一种特殊的:

    from modname import *

    这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。大多数情况, Python程序员不使用这种方法,因为引入的其它来源的命名,很可能覆盖了已有的定义。

    特殊的例子

     

    上图是目录结构

     下面说下文件中的内容

    __init__.py:空

    modue1.py:

    def show_num():
        print("11111")

     modue2.py:

    import modue1
    
    modue1.show_num()

     bin.py:

    from demo import modue2

     当我运行modue2.py的时候,显示:

    当我运行bin.py的时候,显示:

    可以看到找不到包了,产生这个问题的原因就是启动文件是谁的问题。由于启动文件的不同,目录层级不同,导致的搜索路径问题,

    我们可以修改bin.py文件:

    import sys
    print(sys.path)
    from demo import modue2

    得出

    我们在modue2中引入了modue1,它的所在目录是modue下的demo文件夹,而可以看到引包是搜索路径中并没有,所以产生了引包的问题。

    解决的方式有两种

    第一种:修改modue2中的引包方式

    from . import modue1

    第二种:修改sys.path

    修改后的modue2如下

    import sys, os
    
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(BASE_DIR)
    import modue1
    
    modue1.show_num()

    注:这个只是临时修改环境变量

    关于启动文件

    如果一个模块是启动文件的话,我们可以常常看到这样一句:

    if __name__ == '__main__':

     这句话就是判断是不是启动文件的。

    在上面的那个特殊的例子中的bin.py加入:

    print(modue2.__name__)      # demo.modue2
    print(__name__)         # __main__

     可以看到,当以该模块作为启动文件的时候,它的"__name__"为"__main__",而作为引用的modue2的"__name__"则为"demo.modue2"。

    其实在一些功能模块中也会有这样一个判断主模块的语句,因为,模块在进行调试的时候,一般也是在本模块中进行调试,所以会加入这样一句用来调试。而当这个模块被引用的时候,则只会将其功能函数调走,不会执行这个判断语句为真后的调试命令。所以它也起了隔离的效果。

  • 相关阅读:
    几数之和的题目
    File类
    递归
    Collections
    Map集合
    泛型
    类型通配符
    可变参数
    异常
    Collection集合
  • 原文地址:https://www.cnblogs.com/kuxingseng95/p/9453980.html
Copyright © 2020-2023  润新知